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