1*9880d681SAndroid Build Coastguard Worker; RUN: opt -tbaa -basicaa -licm -S < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -aa-pipeline=type-based-aa,basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,loop(licm)' -S %s | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; If we can prove a local is thread local, we can insert stores during 5*9880d681SAndroid Build Coastguard Worker; promotion which wouldn't be legal otherwise. 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 8*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-linux-generic" 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker@p = external global i8* 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdeclare i8* @malloc(i64) 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; Exercise the TLS case 15*9880d681SAndroid Build Coastguard Workerdefine i32* @test(i32 %n) { 16*9880d681SAndroid Build Coastguard Workerentry: 17*9880d681SAndroid Build Coastguard Worker ;; ignore the required null check for simplicity 18*9880d681SAndroid Build Coastguard Worker %mem = call dereferenceable(16) noalias i8* @malloc(i64 16) 19*9880d681SAndroid Build Coastguard Worker %addr = bitcast i8* %mem to i32* 20*9880d681SAndroid Build Coastguard Worker br label %for.body.lr.ph 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerfor.body.lr.ph: ; preds = %entry 23*9880d681SAndroid Build Coastguard Worker br label %for.header 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Workerfor.header: 26*9880d681SAndroid Build Coastguard Worker %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ] 27*9880d681SAndroid Build Coastguard Worker %old = load i32, i32* %addr, align 4 28*9880d681SAndroid Build Coastguard Worker ; deliberate impossible to analyze branch 29*9880d681SAndroid Build Coastguard Worker %guard = load atomic i8*, i8** @p monotonic, align 8 30*9880d681SAndroid Build Coastguard Worker %exitcmp = icmp eq i8* %guard, null 31*9880d681SAndroid Build Coastguard Worker br i1 %exitcmp, label %for.body, label %early-exit 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerearly-exit: 34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: early-exit: 35*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 %new1.lcssa, i32* %addr, align 1 36*9880d681SAndroid Build Coastguard Worker ret i32* null 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Workerfor.body: 39*9880d681SAndroid Build Coastguard Worker %new = add i32 %old, 1 40*9880d681SAndroid Build Coastguard Worker store i32 %new, i32* %addr, align 4 41*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %i.02, 1 42*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %inc, %n 43*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerfor.cond.for.end_crit_edge: ; preds = %for.body 46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: for.cond.for.end_crit_edge: 47*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 %new.lcssa, i32* %addr, align 1 48*9880d681SAndroid Build Coastguard Worker %split = phi i32* [ %addr, %for.body ] 49*9880d681SAndroid Build Coastguard Worker ret i32* null 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Workerdeclare i8* @not_malloc(i64) 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker; Negative test - not TLS 55*9880d681SAndroid Build Coastguard Workerdefine i32* @test_neg(i32 %n) { 56*9880d681SAndroid Build Coastguard Workerentry: 57*9880d681SAndroid Build Coastguard Worker ;; ignore the required null check for simplicity 58*9880d681SAndroid Build Coastguard Worker %mem = call dereferenceable(16) noalias i8* @not_malloc(i64 16) 59*9880d681SAndroid Build Coastguard Worker %addr = bitcast i8* %mem to i32* 60*9880d681SAndroid Build Coastguard Worker br label %for.body.lr.ph 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerfor.body.lr.ph: ; preds = %entry 63*9880d681SAndroid Build Coastguard Worker br label %for.header 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerfor.header: 66*9880d681SAndroid Build Coastguard Worker %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ] 67*9880d681SAndroid Build Coastguard Worker %old = load i32, i32* %addr, align 4 68*9880d681SAndroid Build Coastguard Worker ; deliberate impossible to analyze branch 69*9880d681SAndroid Build Coastguard Worker %guard = load volatile i8*, i8** @p 70*9880d681SAndroid Build Coastguard Worker %exitcmp = icmp eq i8* %guard, null 71*9880d681SAndroid Build Coastguard Worker br i1 %exitcmp, label %for.body, label %early-exit 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Workerearly-exit: 74*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: early-exit: 75*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 76*9880d681SAndroid Build Coastguard Worker ret i32* null 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerfor.body: 79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: for.body: 80*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 %new, i32* %addr, align 4 81*9880d681SAndroid Build Coastguard Worker %new = add i32 %old, 1 82*9880d681SAndroid Build Coastguard Worker store i32 %new, i32* %addr, align 4 83*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %i.02, 1 84*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %inc, %n 85*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Workerfor.cond.for.end_crit_edge: ; preds = %for.body 88*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: for.cond.for.end_crit_edge: 89*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 90*9880d681SAndroid Build Coastguard Worker %split = phi i32* [ %addr, %for.body ] 91*9880d681SAndroid Build Coastguard Worker ret i32* null 92*9880d681SAndroid Build Coastguard Worker} 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker; Negative test - can't speculate load since branch 95*9880d681SAndroid Build Coastguard Worker; may control alignment 96*9880d681SAndroid Build Coastguard Workerdefine i32* @test_neg2(i32 %n) { 97*9880d681SAndroid Build Coastguard Workerentry: 98*9880d681SAndroid Build Coastguard Worker ;; ignore the required null check for simplicity 99*9880d681SAndroid Build Coastguard Worker %mem = call dereferenceable(16) noalias i8* @malloc(i64 16) 100*9880d681SAndroid Build Coastguard Worker %addr = bitcast i8* %mem to i32* 101*9880d681SAndroid Build Coastguard Worker br label %for.body.lr.ph 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Workerfor.body.lr.ph: ; preds = %entry 104*9880d681SAndroid Build Coastguard Worker br label %for.header 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Workerfor.header: 107*9880d681SAndroid Build Coastguard Worker %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ] 108*9880d681SAndroid Build Coastguard Worker ; deliberate impossible to analyze branch 109*9880d681SAndroid Build Coastguard Worker %guard = load volatile i8*, i8** @p 110*9880d681SAndroid Build Coastguard Worker %exitcmp = icmp eq i8* %guard, null 111*9880d681SAndroid Build Coastguard Worker br i1 %exitcmp, label %for.body, label %early-exit 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Workerearly-exit: 114*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: early-exit: 115*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 116*9880d681SAndroid Build Coastguard Worker ret i32* null 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workerfor.body: 119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: for.body: 120*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 %new, i32* %addr, align 4 121*9880d681SAndroid Build Coastguard Worker %old = load i32, i32* %addr, align 4 122*9880d681SAndroid Build Coastguard Worker %new = add i32 %old, 1 123*9880d681SAndroid Build Coastguard Worker store i32 %new, i32* %addr, align 4 124*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %i.02, 1 125*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %inc, %n 126*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Workerfor.cond.for.end_crit_edge: ; preds = %for.body 129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: for.cond.for.end_crit_edge: 130*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 131*9880d681SAndroid Build Coastguard Worker %split = phi i32* [ %addr, %for.body ] 132*9880d681SAndroid Build Coastguard Worker ret i32* null 133*9880d681SAndroid Build Coastguard Worker} 134*9880d681SAndroid Build Coastguard Worker 135