diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1442,7 +1442,11 @@ unsigned Flags = 0; if (I->mayReadFromMemory()) Flags |= SkipReadMem; - if (I->mayHaveSideEffects()) + // For the purposes of hoisting instructions, inalloca allocas are treated as + // having side effects to avoid moving them across stacksave/stackrestore + // boundaries. + if (I->mayHaveSideEffects() || + (isa(I) && cast(I)->isUsedWithInAlloca())) Flags |= SkipSideEffect; if (!isGuaranteedToTransferExecutionToSuccessor(I)) Flags |= SkipImplicitControlFlow; diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-common-skip.ll b/llvm/test/Transforms/SimplifyCFG/hoist-common-skip.ll --- a/llvm/test/Transforms/SimplifyCFG/hoist-common-skip.ll +++ b/llvm/test/Transforms/SimplifyCFG/hoist-common-skip.ll @@ -388,23 +388,24 @@ } ;; Don't hoist stacksaves across inalloca allocas -;; FIXME: currently this is miscompiled define void @f10(i1 %cond) { ; CHECK-LABEL: @f10( ; CHECK-NEXT: [[SS:%.*]] = call ptr @llvm.stacksave() -; CHECK-NEXT: [[SS2:%.*]] = call ptr @llvm.stacksave() -; CHECK-NEXT: [[I2:%.*]] = alloca inalloca i64, align 8 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: ; CHECK-NEXT: [[I1:%.*]] = alloca inalloca i32, align 4 +; CHECK-NEXT: [[SS2:%.*]] = call ptr @llvm.stacksave() +; CHECK-NEXT: [[I2:%.*]] = alloca inalloca i64, align 8 ; CHECK-NEXT: call void @inalloca_i64(ptr inalloca(i64) [[I2]]) ; CHECK-NEXT: call void @llvm.stackrestore(ptr [[SS2]]) ; CHECK-NEXT: call void @inalloca_i32(ptr inalloca(i32) [[I1]]) ; CHECK-NEXT: br label [[END:%.*]] ; CHECK: bb2: ; CHECK-NEXT: [[I3:%.*]] = alloca inalloca i64, align 8 -; CHECK-NEXT: [[TMP1:%.*]] = call ptr @inalloca_i64(ptr inalloca(i64) [[I2]]) -; CHECK-NEXT: call void @llvm.stackrestore(ptr [[SS2]]) +; CHECK-NEXT: [[SS3:%.*]] = call ptr @llvm.stacksave() +; CHECK-NEXT: [[I4:%.*]] = alloca inalloca i64, align 8 +; CHECK-NEXT: [[TMP1:%.*]] = call ptr @inalloca_i64(ptr inalloca(i64) [[I4]]) +; CHECK-NEXT: call void @llvm.stackrestore(ptr [[SS3]]) ; CHECK-NEXT: [[TMP2:%.*]] = call ptr @inalloca_i64(ptr inalloca(i64) [[I3]]) ; CHECK-NEXT: br label [[END]] ; CHECK: end: