1; RUN: opt < %s -basicaa -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@_ZTIi = external constant i8* 71 72; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop. 73; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as 74; expected 75define void @loop_within_tryblock() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 76entry: 77 %a = alloca i32, align 4 78 store i32 0, i32* %a, align 4 79 br label %for.cond 80 81for.cond: 82 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 83 %cmp = icmp slt i32 %i.0, 1024 84 br i1 %cmp, label %for.body, label %for.end 85 86; CHECK: for.body: 87; CHECK-NOT: load 88; CHECK-NOT: store 89; CHECK: invoke 90for.body: 91 %0 = load i32, i32* %a, align 4 92 %add = add nsw i32 %0, 1 93 store i32 %add, i32* %a, align 4 94 invoke void @boo() 95 to label %invoke.cont unwind label %lpad 96 97invoke.cont: 98 br label %for.inc 99 100for.inc: 101 %inc = add nsw i32 %i.0, 1 102 br label %for.cond 103 104; CHECK: lpad: 105; CHECK: store 106; CHECK: br 107lpad: 108 %1 = landingpad { i8*, i32 } 109 catch i8* bitcast (i8** @_ZTIi to i8*) 110 %2 = extractvalue { i8*, i32 } %1, 0 111 %3 = extractvalue { i8*, i32 } %1, 1 112 br label %catch.dispatch 113 114catch.dispatch: 115 %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3 116 %matches = icmp eq i32 %3, %4 117 br i1 %matches, label %catch, label %eh.resume 118 119catch: 120 %5 = call i8* @__cxa_begin_catch(i8* %2) #3 121 %6 = bitcast i8* %5 to i32* 122 %7 = load i32, i32* %6, align 4 123 call void @__cxa_end_catch() #3 124 br label %try.cont 125 126try.cont: 127 ret void 128 129for.end: 130 br label %try.cont 131 132eh.resume: 133 %lpad.val = insertvalue { i8*, i32 } undef, i8* %2, 0 134 %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %3, 1 135 resume { i8*, i32 } %lpad.val3 136} 137 138 139; The malloc'ed memory is not capture and therefore promoted. 140define void @malloc_no_capture() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 141entry: 142 %call = call i8* @malloc(i64 4) 143 %0 = bitcast i8* %call to i32* 144 br label %for.body 145 146; CHECK: for.body: 147; CHECK-NOT: load 148; CHECK-NOT: store 149; CHECK: br 150for.body: 151 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] 152 %1 = load i32, i32* %0, align 4 153 %add = add nsw i32 %1, 1 154 store i32 %add, i32* %0, align 4 155 br label %for.call 156 157for.call: 158 invoke void @boo() 159 to label %invoke.cont unwind label %lpad 160 161invoke.cont: 162 br label %for.latch 163 164for.latch: 165 %inc = add i32 %i.0, 1 166 %cmp = icmp slt i32 %i.0, 1024 167 br i1 %cmp, label %for.body, label %for.end 168 169for.end: 170 br label %fun.ret 171 172lpad: 173 %2 = landingpad { i8*, i32 } 174 catch i8* null 175 %3 = extractvalue { i8*, i32 } %2, 0 176 %4 = extractvalue { i8*, i32 } %2, 1 177 br label %catch 178 179catch: 180 %5 = call i8* @__cxa_begin_catch(i8* %3) #4 181 %6 = bitcast i32* %0 to i8* 182 call void @free(i8* %6) 183 call void @__cxa_end_catch() 184 br label %fun.ret 185 186fun.ret: 187 ret void 188} 189 190; The malloc'ed memory can be captured and therefore not promoted. 191define void @malloc_capture(i32** noalias %A) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 192entry: 193 %call = call i8* @malloc(i64 4) 194 %0 = bitcast i8* %call to i32* 195 br label %for.body 196 197; CHECK: for.body: 198; CHECK: load 199; CHECK: store 200; CHECK: br 201for.body: 202 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] 203 %1 = load i32, i32* %0, align 4 204 %add = add nsw i32 %1, 1 205 store i32 %add, i32* %0, align 4 206 br label %for.call 207 208for.call: 209 invoke void @boo_readnone() 210 to label %invoke.cont unwind label %lpad 211 212invoke.cont: 213 br label %for.latch 214 215for.latch: 216 store i32* %0, i32** %A 217 %inc = add i32 %i.0, 1 218 %cmp = icmp slt i32 %i.0, 1024 219 br i1 %cmp, label %for.body, label %for.end 220 221for.end: 222 br label %fun.ret 223 224lpad: 225 %2 = landingpad { i8*, i32 } 226 catch i8* null 227 %3 = extractvalue { i8*, i32 } %2, 0 228 %4 = extractvalue { i8*, i32 } %2, 1 229 br label %catch 230 231catch: 232 %5 = call i8* @__cxa_begin_catch(i8* %3) #4 233 %6 = bitcast i32* %0 to i8* 234 call void @free(i8* %6) 235 call void @__cxa_end_catch() 236 br label %fun.ret 237 238fun.ret: 239 ret void 240} 241 242; Function Attrs: nounwind 243declare noalias i8* @malloc(i64) 244 245; Function Attrs: nounwind 246declare void @free(i8* nocapture) 247 248declare void @boo() 249 250; This is an artifical example, readnone functions by definition cannot unwind 251; exceptions by calling the C++ exception throwing methods 252; This function should only be used to test malloc_capture. 253declare void @boo_readnone() readnone 254 255declare i32 @__gxx_personality_v0(...) 256 257declare i8* @__cxa_begin_catch(i8*) 258 259declare void @__cxa_end_catch() 260 261declare i32 @llvm.eh.typeid.for(i8*) 262 263declare void @f() uwtable 264