1; RUN: opt < %s -basic-aa -licm -S | FileCheck %s 2; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7; Make sure we don't hoist the store out of the loop; %a would 8; have the wrong value if f() unwinds 9 10define void @test1(i32* nocapture noalias %a, i1 zeroext %y) uwtable { 11entry: 12 br label %for.body 13 14for.body: 15 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 16 %0 = load i32, i32* %a, align 4 17 %add = add nsw i32 %0, 1 18 store i32 %add, i32* %a, align 4 19 br i1 %y, label %if.then, label %for.inc 20 21; CHECK: define void @test1 22; CHECK: load i32, i32* 23; CHECK-NEXT: add 24; CHECK-NEXT: store i32 25 26if.then: 27 tail call void @f() 28 br label %for.inc 29 30for.inc: 31 %inc = add nuw nsw i32 %i.03, 1 32 %exitcond = icmp eq i32 %inc, 10000 33 br i1 %exitcond, label %for.cond.cleanup, label %for.body 34 35for.cond.cleanup: 36 ret void 37} 38 39; We can hoist the store out of the loop here; if f() unwinds, 40; the lifetime of %a ends. 41 42define void @test2(i1 zeroext %y) uwtable { 43entry: 44 %a = alloca i32 45 br label %for.body 46 47for.body: 48 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 49 %0 = load i32, i32* %a, align 4 50 %add = add nsw i32 %0, 1 51 store i32 %add, i32* %a, align 4 52 br i1 %y, label %if.then, label %for.inc 53 54if.then: 55 tail call void @f() 56 br label %for.inc 57 58for.inc: 59 %inc = add nuw nsw i32 %i.03, 1 60 %exitcond = icmp eq i32 %inc, 10000 61 br i1 %exitcond, label %for.cond.cleanup, label %for.body 62 63for.cond.cleanup: 64; CHECK: define void @test2 65; CHECK: store i32 66; CHECK-NEXT: ret void 67 ret void 68} 69 70;; We can promote if the load can be proven safe to speculate, and the 71;; store safe to sink, even if the the store *isn't* must execute. 72define void @test3(i1 zeroext %y) uwtable { 73; CHECK-LABEL: @test3 74entry: 75; CHECK-LABEL: entry: 76; CHECK-NEXT: %a = alloca i32 77; CHECK-NEXT: %a.promoted = load i32, i32* %a, align 4 78 %a = alloca i32 79 br label %for.body 80 81for.body: 82 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 83 %0 = load i32, i32* %a, align 4 84 %add = add nsw i32 %0, 1 85 tail call void @f() 86 store i32 %add, i32* %a, align 4 87 %inc = add nuw nsw i32 %i.03, 1 88 %exitcond = icmp eq i32 %inc, 10000 89 br i1 %exitcond, label %for.cond.cleanup, label %for.body 90 91for.cond.cleanup: 92; CHECK-LABEL: for.cond.cleanup: 93; CHECK: store i32 %add.lcssa, i32* %a, align 4 94; CHECK-NEXT: ret void 95 ret void 96} 97 98;; Same as test3, but with unordered atomics 99define void @test3b(i1 zeroext %y) uwtable { 100; CHECK-LABEL: @test3 101entry: 102; CHECK-LABEL: entry: 103; CHECK-NEXT: %a = alloca i32 104; CHECK-NEXT: %a.promoted = load atomic i32, i32* %a unordered, align 4 105 %a = alloca i32 106 br label %for.body 107 108for.body: 109 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 110 %0 = load atomic i32, i32* %a unordered, align 4 111 %add = add nsw i32 %0, 1 112 tail call void @f() 113 store atomic i32 %add, i32* %a unordered, align 4 114 %inc = add nuw nsw i32 %i.03, 1 115 %exitcond = icmp eq i32 %inc, 10000 116 br i1 %exitcond, label %for.cond.cleanup, label %for.body 117 118for.cond.cleanup: 119; CHECK-LABEL: for.cond.cleanup: 120; CHECK: store atomic i32 %add.lcssa, i32* %a unordered, align 4 121; CHECK-NEXT: ret void 122 ret void 123} 124 125@_ZTIi = external constant i8* 126 127; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop. 128; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as 129; expected 130define void @loop_within_tryblock() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 131entry: 132 %a = alloca i32, align 4 133 store i32 0, i32* %a, align 4 134 br label %for.cond 135 136for.cond: 137 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 138 %cmp = icmp slt i32 %i.0, 1024 139 br i1 %cmp, label %for.body, label %for.end 140 141; CHECK: for.body: 142; CHECK-NOT: load 143; CHECK-NOT: store 144; CHECK: invoke 145for.body: 146 %0 = load i32, i32* %a, align 4 147 %add = add nsw i32 %0, 1 148 store i32 %add, i32* %a, align 4 149 invoke void @boo() 150 to label %invoke.cont unwind label %lpad 151 152invoke.cont: 153 br label %for.inc 154 155for.inc: 156 %inc = add nsw i32 %i.0, 1 157 br label %for.cond 158 159; CHECK: lpad: 160; CHECK: store 161; CHECK: br 162lpad: 163 %1 = landingpad { i8*, i32 } 164 catch i8* bitcast (i8** @_ZTIi to i8*) 165 %2 = extractvalue { i8*, i32 } %1, 0 166 %3 = extractvalue { i8*, i32 } %1, 1 167 br label %catch.dispatch 168 169catch.dispatch: 170 %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3 171 %matches = icmp eq i32 %3, %4 172 br i1 %matches, label %catch, label %eh.resume 173 174catch: 175 %5 = call i8* @__cxa_begin_catch(i8* %2) #3 176 %6 = bitcast i8* %5 to i32* 177 %7 = load i32, i32* %6, align 4 178 call void @__cxa_end_catch() #3 179 br label %try.cont 180 181try.cont: 182 ret void 183 184for.end: 185 br label %try.cont 186 187eh.resume: 188 %lpad.val = insertvalue { i8*, i32 } undef, i8* %2, 0 189 %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %3, 1 190 resume { i8*, i32 } %lpad.val3 191} 192 193 194; The malloc'ed memory is not capture and therefore promoted. 195define void @malloc_no_capture() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 196entry: 197 %call = call i8* @malloc(i64 4) 198 %0 = bitcast i8* %call to i32* 199 br label %for.body 200 201; CHECK: for.body: 202; CHECK-NOT: load 203; CHECK-NOT: store 204; CHECK: br 205for.body: 206 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] 207 %1 = load i32, i32* %0, align 4 208 %add = add nsw i32 %1, 1 209 store i32 %add, i32* %0, align 4 210 br label %for.call 211 212for.call: 213 invoke void @boo() 214 to label %invoke.cont unwind label %lpad 215 216invoke.cont: 217 br label %for.latch 218 219for.latch: 220 %inc = add i32 %i.0, 1 221 %cmp = icmp slt i32 %i.0, 1024 222 br i1 %cmp, label %for.body, label %for.end 223 224for.end: 225 br label %fun.ret 226 227lpad: 228 %2 = landingpad { i8*, i32 } 229 catch i8* null 230 %3 = extractvalue { i8*, i32 } %2, 0 231 %4 = extractvalue { i8*, i32 } %2, 1 232 br label %catch 233 234catch: 235 %5 = call i8* @__cxa_begin_catch(i8* %3) #4 236 %6 = bitcast i32* %0 to i8* 237 call void @free(i8* %6) 238 call void @__cxa_end_catch() 239 br label %fun.ret 240 241fun.ret: 242 ret void 243} 244 245; The malloc'ed memory can be captured and therefore not promoted. 246define void @malloc_capture(i32** noalias %A) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 247entry: 248 %call = call i8* @malloc(i64 4) 249 %0 = bitcast i8* %call to i32* 250 br label %for.body 251 252; CHECK: for.body: 253; CHECK: load 254; CHECK: store 255; CHECK: br 256for.body: 257 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] 258 %1 = load i32, i32* %0, align 4 259 %add = add nsw i32 %1, 1 260 store i32 %add, i32* %0, align 4 261 br label %for.call 262 263for.call: 264 invoke void @boo_readnone() 265 to label %invoke.cont unwind label %lpad 266 267invoke.cont: 268 br label %for.latch 269 270for.latch: 271 store i32* %0, i32** %A 272 %inc = add i32 %i.0, 1 273 %cmp = icmp slt i32 %i.0, 1024 274 br i1 %cmp, label %for.body, label %for.end 275 276for.end: 277 br label %fun.ret 278 279lpad: 280 %2 = landingpad { i8*, i32 } 281 catch i8* null 282 %3 = extractvalue { i8*, i32 } %2, 0 283 %4 = extractvalue { i8*, i32 } %2, 1 284 br label %catch 285 286catch: 287 %5 = call i8* @__cxa_begin_catch(i8* %3) #4 288 %6 = bitcast i32* %0 to i8* 289 call void @free(i8* %6) 290 call void @__cxa_end_catch() 291 br label %fun.ret 292 293fun.ret: 294 ret void 295} 296 297; Function Attrs: nounwind 298declare noalias i8* @malloc(i64) 299 300; Function Attrs: nounwind 301declare void @free(i8* nocapture) 302 303declare void @boo() 304 305; This is an artifical example, readnone functions by definition cannot unwind 306; exceptions by calling the C++ exception throwing methods 307; This function should only be used to test malloc_capture. 308declare void @boo_readnone() readnone 309 310declare i32 @__gxx_personality_v0(...) 311 312declare i8* @__cxa_begin_catch(i8*) 313 314declare void @__cxa_end_catch() 315 316declare i32 @llvm.eh.typeid.for(i8*) 317 318declare void @f() uwtable 319