1 ; RUN: opt < %s -basicaa -gvn -dse -S | FileCheck %s 2 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" 3 4 declare void @llvm.lifetime.end(i64, i8* nocapture) 5 6 declare void @external(i32*) 7 8 define i32 @test0(i8* %P) { 9 %A = alloca i32 10 call void @external(i32* %A) 11 12 store i32 0, i32* %A 13 14 call void @llvm.memset.p0i8.i32(i8* %P, i8 0, i32 42, i32 1, i1 false) 15 16 %B = load i32* %A 17 ret i32 %B 18 19 ; CHECK: @test0 20 ; CHECK: ret i32 0 21 } 22 23 define i8 @test1() { 24 ; CHECK: @test1 25 %A = alloca i8 26 %B = alloca i8 27 28 store i8 2, i8* %B ;; Not written to by memcpy 29 30 call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i32 0, i1 false) 31 32 %C = load i8* %B 33 ret i8 %C 34 ; CHECK: ret i8 2 35 } 36 37 define i8 @test2(i8* %P) { 38 ; CHECK: @test2 39 %P2 = getelementptr i8* %P, i32 127 40 store i8 1, i8* %P2 ;; Not dead across memset 41 call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i32 0, i1 false) 42 %A = load i8* %P2 43 ret i8 %A 44 ; CHECK: ret i8 1 45 } 46 47 define i8 @test2a(i8* %P) { 48 ; CHECK: @test2 49 %P2 = getelementptr i8* %P, i32 126 50 51 ;; FIXME: DSE isn't zapping this dead store. 52 store i8 1, i8* %P2 ;; Dead, clobbered by memset. 53 54 call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i32 0, i1 false) 55 %A = load i8* %P2 56 ret i8 %A 57 ; CHECK-NOT: load 58 ; CHECK: ret i8 2 59 } 60 61 define void @test3(i8* %P, i8 %X) { 62 ; CHECK: @test3 63 ; CHECK-NOT: store 64 ; CHECK-NOT: %Y 65 %Y = add i8 %X, 1 ;; Dead, because the only use (the store) is dead. 66 67 %P2 = getelementptr i8* %P, i32 2 68 store i8 %Y, i8* %P2 ;; Not read by lifetime.end, should be removed. 69 ; CHECK: store i8 2, i8* %P2 70 call void @llvm.lifetime.end(i64 1, i8* %P) 71 store i8 2, i8* %P2 72 ; CHECK-NOT: store 73 ret void 74 ; CHECK: ret void 75 } 76 77 define void @test3a(i8* %P, i8 %X) { 78 ; CHECK: @test3a 79 %Y = add i8 %X, 1 ;; Dead, because the only use (the store) is dead. 80 81 %P2 = getelementptr i8* %P, i32 2 82 store i8 %Y, i8* %P2 83 ; CHECK-NEXT: call void @llvm.lifetime.end 84 call void @llvm.lifetime.end(i64 10, i8* %P) 85 ret void 86 ; CHECK-NEXT: ret void 87 } 88 89 @G1 = external global i32 90 @G2 = external global [4000 x i32] 91 92 define i32 @test4(i8* %P) { 93 %tmp = load i32* @G1 94 call void @llvm.memset.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8 0, i32 4000, i32 1, i1 false) 95 %tmp2 = load i32* @G1 96 %sub = sub i32 %tmp2, %tmp 97 ret i32 %sub 98 ; CHECK: @test4 99 ; CHECK-NOT: load 100 ; CHECK: memset.p0i8.i32 101 ; CHECK-NOT: load 102 ; CHECK: ret i32 0 103 } 104 105 ; Verify that basicaa is handling variable length memcpy, knowing it doesn't 106 ; write to G1. 107 define i32 @test5(i8* %P, i32 %Len) { 108 %tmp = load i32* @G1 109 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8* bitcast (i32* @G1 to i8*), i32 %Len, i32 1, i1 false) 110 %tmp2 = load i32* @G1 111 %sub = sub i32 %tmp2, %tmp 112 ret i32 %sub 113 ; CHECK: @test5 114 ; CHECK-NOT: load 115 ; CHECK: memcpy.p0i8.p0i8.i32 116 ; CHECK-NOT: load 117 ; CHECK: ret i32 0 118 } 119 120 define i8 @test6(i8* %p, i8* noalias %a) { 121 %x = load i8* %a 122 %t = va_arg i8* %p, float 123 %y = load i8* %a 124 %z = add i8 %x, %y 125 ret i8 %z 126 ; CHECK: @test6 127 ; CHECK: load i8* %a 128 ; CHECK-NOT: load 129 ; CHECK: ret 130 } 131 132 ; PR10628 133 declare void @test7decl(i32* nocapture %x) 134 define i32 @test7() nounwind uwtable ssp { 135 entry: 136 %x = alloca i32, align 4 137 store i32 0, i32* %x, align 4 138 %add.ptr = getelementptr inbounds i32* %x, i64 1 139 call void @test7decl(i32* %add.ptr) 140 %tmp = load i32* %x, align 4 141 ret i32 %tmp 142 ; CHECK: @test7( 143 ; CHECK: store i32 0 144 ; CHECK: call void @test7decl 145 ; CHECK: load i32* 146 } 147 148 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind 149 declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i32, i1) nounwind 150 declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i32, i1) nounwind 151 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 152