mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[Coroutines] Do not add alloca to the frame if the size is 0
This patch is to address https://bugs.llvm.org/show_bug.cgi?id=49916. When the size of an alloca is 0, it will trigger an assertion in OptimizedStructLayout when being added to the frame. Fix it by not adding it at all. We return index 0 (beginning of the frame) for all 0-sized allocas. Differential Revision: https://reviews.llvm.org/D101841
This commit is contained in:
parent
4d2b659c90
commit
cb79e5070e
@ -453,6 +453,12 @@ public:
|
|||||||
// The field size is always the alloc size of the type.
|
// The field size is always the alloc size of the type.
|
||||||
uint64_t FieldSize = DL.getTypeAllocSize(Ty);
|
uint64_t FieldSize = DL.getTypeAllocSize(Ty);
|
||||||
|
|
||||||
|
// For an alloca with size=0, we don't need to add a field and they
|
||||||
|
// can just point to any index in the frame. Use index 0.
|
||||||
|
if (FieldSize == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// The field alignment might not be the type alignment, but we need
|
// The field alignment might not be the type alignment, but we need
|
||||||
// to remember the type alignment anyway to build the type.
|
// to remember the type alignment anyway to build the type.
|
||||||
Align TyAlignment = DL.getABITypeAlign(Ty);
|
Align TyAlignment = DL.getABITypeAlign(Ty);
|
||||||
|
81
test/Transforms/Coroutines/coro-zero-alloca.ll
Normal file
81
test/Transforms/Coroutines/coro-zero-alloca.ll
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
; RUN: opt < %s -O2 --enable-coroutines -S | FileCheck %s
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
target triple = "x86_64--linux"
|
||||||
|
|
||||||
|
declare i8* @malloc(i64)
|
||||||
|
declare void @free(i8*)
|
||||||
|
declare void @usePointer(i8*)
|
||||||
|
declare void @usePointer2([0 x i8]*)
|
||||||
|
|
||||||
|
declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*)
|
||||||
|
declare i64 @llvm.coro.size.i64()
|
||||||
|
declare i8* @llvm.coro.begin(token, i8* writeonly)
|
||||||
|
declare i8 @llvm.coro.suspend(token, i1)
|
||||||
|
declare i1 @llvm.coro.end(i8*, i1)
|
||||||
|
declare i8* @llvm.coro.free(token, i8* nocapture readonly)
|
||||||
|
declare token @llvm.coro.save(i8*)
|
||||||
|
|
||||||
|
define void @foo() {
|
||||||
|
entry:
|
||||||
|
%a0 = alloca [0 x i8]
|
||||||
|
%a1 = alloca i32
|
||||||
|
%a2 = alloca [0 x i8]
|
||||||
|
%a3 = alloca [0 x i8]
|
||||||
|
%a4 = alloca i16
|
||||||
|
%a5 = alloca [0 x i8]
|
||||||
|
%a0.cast = bitcast [0 x i8]* %a0 to i8*
|
||||||
|
%a1.cast = bitcast i32* %a1 to i8*
|
||||||
|
%a2.cast = bitcast [0 x i8]* %a2 to i8*
|
||||||
|
%a3.cast = bitcast [0 x i8]* %a3 to i8*
|
||||||
|
%a4.cast = bitcast i16* %a4 to i8*
|
||||||
|
%coro.id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
|
||||||
|
%coro.size = call i64 @llvm.coro.size.i64()
|
||||||
|
%coro.alloc = call i8* @malloc(i64 %coro.size)
|
||||||
|
%coro.state = call i8* @llvm.coro.begin(token %coro.id, i8* %coro.alloc)
|
||||||
|
%coro.save = call token @llvm.coro.save(i8* %coro.state)
|
||||||
|
%call.suspend = call i8 @llvm.coro.suspend(token %coro.save, i1 false)
|
||||||
|
switch i8 %call.suspend, label %suspend [
|
||||||
|
i8 0, label %wakeup
|
||||||
|
i8 1, label %cleanup
|
||||||
|
]
|
||||||
|
|
||||||
|
wakeup: ; preds = %entry
|
||||||
|
call void @usePointer(i8* %a0.cast)
|
||||||
|
call void @usePointer(i8* %a1.cast)
|
||||||
|
call void @usePointer(i8* %a2.cast)
|
||||||
|
call void @usePointer(i8* %a3.cast)
|
||||||
|
call void @usePointer(i8* %a4.cast)
|
||||||
|
call void @usePointer2([0 x i8]* %a5)
|
||||||
|
br label %cleanup
|
||||||
|
|
||||||
|
suspend: ; preds = %cleanup, %entry
|
||||||
|
%unused = call i1 @llvm.coro.end(i8* %coro.state, i1 false)
|
||||||
|
ret void
|
||||||
|
|
||||||
|
cleanup: ; preds = %wakeup, %entry
|
||||||
|
%coro.memFree = call i8* @llvm.coro.free(token %coro.id, i8* %coro.state)
|
||||||
|
call void @free(i8* %coro.memFree)
|
||||||
|
br label %suspend
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: %foo.Frame = type { void (%foo.Frame*)*, void (%foo.Frame*)*, i32, i16, i1 }
|
||||||
|
|
||||||
|
; CHECK-LABEL: define internal fastcc void @foo.resume(%foo.Frame* noalias nonnull align 8 dereferenceable(24) %FramePtr) {
|
||||||
|
; CHECK-NEXT: entry.resume:
|
||||||
|
; CHECK-NEXT: %vFrame = bitcast %foo.Frame* %FramePtr to i8*
|
||||||
|
; CHECK-NEXT: %a1.reload.addr = getelementptr inbounds %foo.Frame, %foo.Frame* %FramePtr, i64 0, i32 2
|
||||||
|
; CHECK-NEXT: %a4.reload.addr = getelementptr inbounds %foo.Frame, %foo.Frame* %FramePtr, i64 0, i32 3
|
||||||
|
; CHECK-NEXT: %a0.reload.addr = bitcast %foo.Frame* %FramePtr to [0 x i8]*
|
||||||
|
; CHECK-NEXT: %a4.cast = bitcast i16* %a4.reload.addr to i8*
|
||||||
|
; CHECK-NEXT: %a3.cast = bitcast %foo.Frame* %FramePtr to i8*
|
||||||
|
; CHECK-NEXT: %a1.cast = bitcast i32* %a1.reload.addr to i8*
|
||||||
|
; CHECK-NEXT: call void @usePointer(i8* nonnull %a3.cast)
|
||||||
|
; CHECK-NEXT: call void @usePointer(i8* nonnull %a1.cast)
|
||||||
|
; CHECK-NEXT: call void @usePointer(i8* nonnull %a3.cast)
|
||||||
|
; CHECK-NEXT: call void @usePointer(i8* nonnull %a3.cast)
|
||||||
|
; CHECK-NEXT: call void @usePointer(i8* nonnull %a4.cast)
|
||||||
|
; CHECK-NEXT: call void @usePointer2([0 x i8]* nonnull %a0.reload.addr)
|
||||||
|
; CHECK-NEXT: call void @free(i8* %vFrame)
|
||||||
|
; CHECK-NEXT: ret void
|
||||||
|
; CHECK-NEXT: }
|
Loading…
Reference in New Issue
Block a user