Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt < %s -instcombine -S | FileCheck %s
      2 
      3 @glob = global i32 0
      4 
      5 declare i8* @llvm.stacksave()
      6 declare void @llvm.stackrestore(i8*)
      7 
      8 ;; Test that llvm.stackrestore is removed when possible.
      9 define i32* @test1(i32 %P) {
     10 	%tmp = call i8* @llvm.stacksave( )
     11 	call void @llvm.stackrestore( i8* %tmp ) ;; not restoring anything
     12 	%A = alloca i32, i32 %P		
     13 	ret i32* %A
     14 }
     15 
     16 ; CHECK-LABEL: define i32* @test1(
     17 ; CHECK-NOT: call void @llvm.stackrestore
     18 ; CHECK: ret i32*
     19 
     20 define void @test2(i8* %X) {
     21 	call void @llvm.stackrestore( i8* %X )  ;; no allocas before return.
     22 	ret void
     23 }
     24 
     25 ; CHECK-LABEL: define void @test2(
     26 ; CHECK-NOT: call void @llvm.stackrestore
     27 ; CHECK: ret void
     28 
     29 define void @foo(i32 %size) nounwind  {
     30 entry:
     31 	%tmp118124 = icmp sgt i32 %size, 0		; <i1> [#uses=1]
     32 	br i1 %tmp118124, label %bb.preheader, label %return
     33 
     34 bb.preheader:		; preds = %entry
     35 	%tmp25 = add i32 %size, -1		; <i32> [#uses=1]
     36 	%tmp125 = icmp slt i32 %size, 1		; <i1> [#uses=1]
     37 	%smax = select i1 %tmp125, i32 1, i32 %size		; <i32> [#uses=1]
     38 	br label %bb
     39 
     40 bb:		; preds = %bb, %bb.preheader
     41 	%i.0.reg2mem.0 = phi i32 [ 0, %bb.preheader ], [ %indvar.next, %bb ]		; <i32> [#uses=2]
     42 	%tmp = call i8* @llvm.stacksave( )		; <i8*> [#uses=1]
     43 	%tmp23 = alloca i8, i32 %size		; <i8*> [#uses=2]
     44 	%tmp27 = getelementptr i8, i8* %tmp23, i32 %tmp25		; <i8*> [#uses=1]
     45 	store i8 0, i8* %tmp27, align 1
     46 	%tmp28 = call i8* @llvm.stacksave( )		; <i8*> [#uses=1]
     47 	%tmp52 = alloca i8, i32 %size		; <i8*> [#uses=1]
     48 	%tmp53 = call i8* @llvm.stacksave( )		; <i8*> [#uses=1]
     49 	%tmp77 = alloca i8, i32 %size		; <i8*> [#uses=1]
     50 	%tmp78 = call i8* @llvm.stacksave( )		; <i8*> [#uses=1]
     51 	%tmp102 = alloca i8, i32 %size		; <i8*> [#uses=1]
     52 	call void @bar( i32 %i.0.reg2mem.0, i8* %tmp23, i8* %tmp52, i8* %tmp77, i8* %tmp102, i32 %size ) nounwind 
     53 	call void @llvm.stackrestore( i8* %tmp78 )
     54 	call void @llvm.stackrestore( i8* %tmp53 )
     55 	call void @llvm.stackrestore( i8* %tmp28 )
     56 	call void @llvm.stackrestore( i8* %tmp )
     57 	%indvar.next = add i32 %i.0.reg2mem.0, 1		; <i32> [#uses=2]
     58 	%exitcond = icmp eq i32 %indvar.next, %smax		; <i1> [#uses=1]
     59 	br i1 %exitcond, label %return, label %bb
     60 
     61 return:		; preds = %bb, %entry
     62 	ret void
     63 }
     64 
     65 ; CHECK-LABEL: define void @foo(
     66 ; CHECK: %tmp = call i8* @llvm.stacksave()
     67 ; CHECK: alloca i8
     68 ; CHECK-NOT: stacksave
     69 ; CHECK: call void @bar(
     70 ; CHECK-NEXT: call void @llvm.stackrestore(i8* %tmp)
     71 ; CHECK: ret void
     72 
     73 declare void @bar(i32, i8*, i8*, i8*, i8*, i32)
     74 
     75 declare void @inalloca_callee(i32* inalloca)
     76 
     77 define void @test3(i32 %c) {
     78 entry:
     79   br label %loop
     80 
     81 loop:
     82   %i = phi i32 [0, %entry], [%i1, %loop]
     83   %save1 = call i8* @llvm.stacksave()
     84   %argmem = alloca inalloca i32
     85   store i32 0, i32* %argmem
     86   call void @inalloca_callee(i32* inalloca %argmem)
     87 
     88   ; This restore cannot be deleted, the restore below does not make it dead.
     89   call void @llvm.stackrestore(i8* %save1)
     90 
     91   ; FIXME: We should be able to remove this save/restore pair, but we don't.
     92   %save2 = call i8* @llvm.stacksave()
     93   store i32 0, i32* @glob
     94   call void @llvm.stackrestore(i8* %save2)
     95   %i1 = add i32 1, %i
     96   %done = icmp eq i32 %i1, %c
     97   br i1 %done, label %loop, label %return
     98 
     99 return:
    100   ret void
    101 }
    102 
    103 ; CHECK-LABEL: define void @test3(
    104 ; CHECK: loop:
    105 ; CHECK: %i = phi i32 [ 0, %entry ], [ %i1, %loop ]
    106 ; CHECK: %save1 = call i8* @llvm.stacksave()
    107 ; CHECK: %argmem = alloca inalloca i32
    108 ; CHECK: store i32 0, i32* %argmem
    109 ; CHECK: call void @inalloca_callee(i32* inalloca {{.*}} %argmem)
    110 ; CHECK: call void @llvm.stackrestore(i8* %save1)
    111 ; CHECK: br i1 %done, label %loop, label %return
    112 ; CHECK: ret void
    113