1; RUN: opt -passes=instcombine -S < %s | FileCheck %s 2 3target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" 4target triple = "i686-unknown-linux-gnu" 5 6; Check that instcombine doesn't sink dynamic allocas across llvm.stacksave. 7 8; Helper to generate branch conditions. 9declare i1 @cond() 10 11declare ptr @use_and_return(ptr) 12 13declare ptr @llvm.stacksave() #0 14 15declare void @llvm.stackrestore(ptr) #0 16 17define void @foo(i32 %x) { 18entry: 19 %c1 = call i1 @cond() 20 br i1 %c1, label %ret, label %nonentry 21 22nonentry: ; preds = %entry 23 %argmem = alloca i32, i32 %x, align 4 24 %sp = call ptr @llvm.stacksave() 25 %c2 = call i1 @cond() 26 br i1 %c2, label %ret, label %sinktarget 27 28sinktarget: ; preds = %nonentry 29 ; Arrange for there to be a single use of %argmem by returning it. 30 %p = call ptr @use_and_return(ptr nonnull %argmem) 31 store i32 13, ptr %p, align 4 32 call void @llvm.stackrestore(ptr %sp) 33 %0 = call ptr @use_and_return(ptr %p) 34 br label %ret 35 36ret: ; preds = %sinktarget, %nonentry, %entry 37 ret void 38} 39 40; CHECK-LABEL: define void @foo(i32 %x) 41; CHECK: nonentry: 42; CHECK: %argmem = alloca i32, i32 %x 43; CHECK: %sp = call ptr @llvm.stacksave.p0() 44; CHECK: %c2 = call i1 @cond() 45; CHECK: br i1 %c2, label %ret, label %sinktarget 46; CHECK: sinktarget: 47; CHECK: %p = call ptr @use_and_return(ptr nonnull %argmem) 48; CHECK: store i32 13, ptr %p 49; CHECK: call void @llvm.stackrestore.p0(ptr %sp) 50; CHECK: %0 = call ptr @use_and_return(ptr nonnull %p) 51 52attributes #0 = { nounwind } 53