xref: /aosp_15_r20/external/llvm/test/Transforms/LICM/promote-tls.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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