John Bauman | 66b8ab2 | 2014-05-06 15:57:45 -0400 | [diff] [blame] | 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
|