1 ; RUN: opt < %s -S -early-cse | FileCheck %s 2 ; RUN: opt < %s -S -basicaa -early-cse-memssa | FileCheck %s 3 ; RUN: opt < %s -S -passes=early-cse | FileCheck %s 4 5 declare void @llvm.assume(i1) nounwind 6 7 ; CHECK-LABEL: @test1( 8 define void @test1(i8 %V, i32 *%P) { 9 %A = bitcast i64 42 to double ;; dead 10 %B = add i32 4, 19 ;; constant folds 11 store i32 %B, i32* %P 12 ; CHECK-NEXT: store i32 23, i32* %P 13 14 %C = zext i8 %V to i32 15 %D = zext i8 %V to i32 ;; CSE 16 store volatile i32 %C, i32* %P 17 store volatile i32 %D, i32* %P 18 ; CHECK-NEXT: %C = zext i8 %V to i32 19 ; CHECK-NEXT: store volatile i32 %C 20 ; CHECK-NEXT: store volatile i32 %C 21 22 %E = add i32 %C, %C 23 %F = add i32 %C, %C 24 store volatile i32 %E, i32* %P 25 store volatile i32 %F, i32* %P 26 ; CHECK-NEXT: %E = add i32 %C, %C 27 ; CHECK-NEXT: store volatile i32 %E 28 ; CHECK-NEXT: store volatile i32 %E 29 30 %G = add nuw i32 %C, %C 31 store volatile i32 %G, i32* %P 32 ; CHECK-NEXT: store volatile i32 %E 33 ret void 34 } 35 36 37 ;; Simple load value numbering. 38 ; CHECK-LABEL: @test2( 39 define i32 @test2(i32 *%P) { 40 %V1 = load i32, i32* %P 41 %V2 = load i32, i32* %P 42 %Diff = sub i32 %V1, %V2 43 ret i32 %Diff 44 ; CHECK: ret i32 0 45 } 46 47 ; CHECK-LABEL: @test2a( 48 define i32 @test2a(i32 *%P, i1 %b) { 49 %V1 = load i32, i32* %P 50 tail call void @llvm.assume(i1 %b) 51 %V2 = load i32, i32* %P 52 %Diff = sub i32 %V1, %V2 53 ret i32 %Diff 54 ; CHECK: ret i32 0 55 } 56 57 ;; Cross block load value numbering. 58 ; CHECK-LABEL: @test3( 59 define i32 @test3(i32 *%P, i1 %Cond) { 60 %V1 = load i32, i32* %P 61 br i1 %Cond, label %T, label %F 62 T: 63 store i32 4, i32* %P 64 ret i32 42 65 F: 66 %V2 = load i32, i32* %P 67 %Diff = sub i32 %V1, %V2 68 ret i32 %Diff 69 ; CHECK: F: 70 ; CHECK: ret i32 0 71 } 72 73 ; CHECK-LABEL: @test3a( 74 define i32 @test3a(i32 *%P, i1 %Cond, i1 %b) { 75 %V1 = load i32, i32* %P 76 br i1 %Cond, label %T, label %F 77 T: 78 store i32 4, i32* %P 79 ret i32 42 80 F: 81 tail call void @llvm.assume(i1 %b) 82 %V2 = load i32, i32* %P 83 %Diff = sub i32 %V1, %V2 84 ret i32 %Diff 85 ; CHECK: F: 86 ; CHECK: ret i32 0 87 } 88 89 ;; Cross block load value numbering stops when stores happen. 90 ; CHECK-LABEL: @test4( 91 define i32 @test4(i32 *%P, i1 %Cond) { 92 %V1 = load i32, i32* %P 93 br i1 %Cond, label %T, label %F 94 T: 95 ret i32 42 96 F: 97 ; Clobbers V1 98 store i32 42, i32* %P 99 100 %V2 = load i32, i32* %P 101 %Diff = sub i32 %V1, %V2 102 ret i32 %Diff 103 ; CHECK: F: 104 ; CHECK: ret i32 %Diff 105 } 106 107 declare i32 @func(i32 *%P) readonly 108 109 ;; Simple call CSE'ing. 110 ; CHECK-LABEL: @test5( 111 define i32 @test5(i32 *%P) { 112 %V1 = call i32 @func(i32* %P) 113 %V2 = call i32 @func(i32* %P) 114 %Diff = sub i32 %V1, %V2 115 ret i32 %Diff 116 ; CHECK: ret i32 0 117 } 118 119 ;; Trivial Store->load forwarding 120 ; CHECK-LABEL: @test6( 121 define i32 @test6(i32 *%P) { 122 store i32 42, i32* %P 123 %V1 = load i32, i32* %P 124 ret i32 %V1 125 ; CHECK: ret i32 42 126 } 127 128 ; CHECK-LABEL: @test6a( 129 define i32 @test6a(i32 *%P, i1 %b) { 130 store i32 42, i32* %P 131 tail call void @llvm.assume(i1 %b) 132 %V1 = load i32, i32* %P 133 ret i32 %V1 134 ; CHECK: ret i32 42 135 } 136 137 ;; Trivial dead store elimination. 138 ; CHECK-LABEL: @test7( 139 define void @test7(i32 *%P) { 140 store i32 42, i32* %P 141 store i32 45, i32* %P 142 ret void 143 ; CHECK-NEXT: store i32 45 144 ; CHECK-NEXT: ret void 145 } 146 147 ;; Readnone functions aren't invalidated by stores. 148 ; CHECK-LABEL: @test8( 149 define i32 @test8(i32 *%P) { 150 %V1 = call i32 @func(i32* %P) readnone 151 store i32 4, i32* %P 152 %V2 = call i32 @func(i32* %P) readnone 153 %Diff = sub i32 %V1, %V2 154 ret i32 %Diff 155 ; CHECK: ret i32 0 156 } 157 158 ;; Trivial DSE can't be performed across a readonly call. The call 159 ;; can observe the earlier write. 160 ; CHECK-LABEL: @test9( 161 define i32 @test9(i32 *%P) { 162 store i32 4, i32* %P 163 %V1 = call i32 @func(i32* %P) readonly 164 store i32 5, i32* %P 165 ret i32 %V1 166 ; CHECK: store i32 4, i32* %P 167 ; CHECK-NEXT: %V1 = call i32 @func(i32* %P) 168 ; CHECK-NEXT: store i32 5, i32* %P 169 ; CHECK-NEXT: ret i32 %V1 170 } 171 172 ;; Trivial DSE can be performed across a readnone call. 173 ; CHECK-LABEL: @test10 174 define i32 @test10(i32 *%P) { 175 store i32 4, i32* %P 176 %V1 = call i32 @func(i32* %P) readnone 177 store i32 5, i32* %P 178 ret i32 %V1 179 ; CHECK-NEXT: %V1 = call i32 @func(i32* %P) 180 ; CHECK-NEXT: store i32 5, i32* %P 181 ; CHECK-NEXT: ret i32 %V1 182 } 183 184 ;; Trivial dead store elimination - should work for an entire series of dead stores too. 185 ; CHECK-LABEL: @test11( 186 define void @test11(i32 *%P) { 187 store i32 42, i32* %P 188 store i32 43, i32* %P 189 store i32 44, i32* %P 190 store i32 45, i32* %P 191 ret void 192 ; CHECK-NEXT: store i32 45 193 ; CHECK-NEXT: ret void 194 } 195 196 ; CHECK-LABEL: @test12( 197 define i32 @test12(i1 %B, i32* %P1, i32* %P2) { 198 %load0 = load i32, i32* %P1 199 %1 = load atomic i32, i32* %P2 seq_cst, align 4 200 %load1 = load i32, i32* %P1 201 %sel = select i1 %B, i32 %load0, i32 %load1 202 ret i32 %sel 203 ; CHECK: load i32, i32* %P1 204 ; CHECK: load i32, i32* %P1 205 } 206 207 define void @dse1(i32 *%P) { 208 ; CHECK-LABEL: @dse1 209 ; CHECK-NOT: store 210 %v = load i32, i32* %P 211 store i32 %v, i32* %P 212 ret void 213 } 214 215 define void @dse2(i32 *%P) { 216 ; CHECK-LABEL: @dse2 217 ; CHECK-NOT: store 218 %v = load atomic i32, i32* %P seq_cst, align 4 219 store i32 %v, i32* %P 220 ret void 221 } 222 223 define void @dse3(i32 *%P) { 224 ; CHECK-LABEL: @dse3 225 ; CHECK-NOT: store 226 %v = load atomic i32, i32* %P seq_cst, align 4 227 store atomic i32 %v, i32* %P unordered, align 4 228 ret void 229 } 230 231 define i32 @dse4(i32 *%P, i32 *%Q) { 232 ; CHECK-LABEL: @dse4 233 ; CHECK-NOT: store 234 ; CHECK: ret i32 0 235 %a = load i32, i32* %Q 236 %v = load atomic i32, i32* %P unordered, align 4 237 store atomic i32 %v, i32* %P unordered, align 4 238 %b = load i32, i32* %Q 239 %res = sub i32 %a, %b 240 ret i32 %res 241 } 242 243 ; Note that in this example, %P and %Q could in fact be the same 244 ; pointer. %v could be different than the value observed for %a 245 ; and that's okay because we're using relaxed memory ordering. 246 ; The only guarantee we have to provide is that each of the loads 247 ; has to observe some value written to that location. We do 248 ; not have to respect the order in which those writes were done. 249 define i32 @dse5(i32 *%P, i32 *%Q) { 250 ; CHECK-LABEL: @dse5 251 ; CHECK-NOT: store 252 ; CHECK: ret i32 0 253 %v = load atomic i32, i32* %P unordered, align 4 254 %a = load atomic i32, i32* %Q unordered, align 4 255 store atomic i32 %v, i32* %P unordered, align 4 256 %b = load atomic i32, i32* %Q unordered, align 4 257 %res = sub i32 %a, %b 258 ret i32 %res 259 } 260 261 262 define void @dse_neg1(i32 *%P) { 263 ; CHECK-LABEL: @dse_neg1 264 ; CHECK: store 265 %v = load i32, i32* %P 266 store i32 5, i32* %P 267 ret void 268 } 269 270 ; Could remove the store, but only if ordering was somehow 271 ; encoded. 272 define void @dse_neg2(i32 *%P) { 273 ; CHECK-LABEL: @dse_neg2 274 ; CHECK: store 275 %v = load i32, i32* %P 276 store atomic i32 %v, i32* %P seq_cst, align 4 277 ret void 278 } 279 280 @c = external global i32, align 4 281 declare i32 @reads_c(i32 returned) 282 define void @pr28763() { 283 entry: 284 ; CHECK-LABEL: @pr28763( 285 ; CHECK: store i32 0, i32* @c, align 4 286 ; CHECK: call i32 @reads_c(i32 0) 287 ; CHECK: store i32 2, i32* @c, align 4 288 %load = load i32, i32* @c, align 4 289 store i32 0, i32* @c, align 4 290 %call = call i32 @reads_c(i32 0) 291 store i32 2, i32* @c, align 4 292 ret void 293 } 294