1
0
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:
Xun Li 2021-05-04 11:11:43 -07:00
parent 4d2b659c90
commit cb79e5070e
2 changed files with 87 additions and 0 deletions

View File

@ -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);

View 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: }