xref: /aosp_15_r20/external/llvm/test/Transforms/LoopUnswitch/msan.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -loop-unswitch -verify-loop-info -S < %s 2>&1 | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker@sink = global i32 0, align 4
4*9880d681SAndroid Build Coastguard Worker@y = global i64 0, align 8
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; The following is approximately:
7*9880d681SAndroid Build Coastguard Worker; void f(bool x, int p, int q) {
8*9880d681SAndroid Build Coastguard Worker;   volatile bool x2 = x;
9*9880d681SAndroid Build Coastguard Worker;   for (int i = 0; i < 1; ++i) {
10*9880d681SAndroid Build Coastguard Worker;     if (x2) {
11*9880d681SAndroid Build Coastguard Worker;       if (y)
12*9880d681SAndroid Build Coastguard Worker;         sink = p;
13*9880d681SAndroid Build Coastguard Worker;       else
14*9880d681SAndroid Build Coastguard Worker;         sink = q;
15*9880d681SAndroid Build Coastguard Worker;     }
16*9880d681SAndroid Build Coastguard Worker;   }
17*9880d681SAndroid Build Coastguard Worker; }
18*9880d681SAndroid Build Coastguard Worker; With MemorySanitizer, the loop can not be unswitched on "y", because "y" could
19*9880d681SAndroid Build Coastguard Worker; be uninitialized when x == false.
20*9880d681SAndroid Build Coastguard Worker; Test that the branch on "y" is inside the loop (after the first unconditional
21*9880d681SAndroid Build Coastguard Worker; branch).
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Workerdefine void @may_not_execute(i1 zeroext %x, i32 %p, i32 %q) sanitize_memory {
24*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @may_not_execute(
25*9880d681SAndroid Build Coastguard Workerentry:
26*9880d681SAndroid Build Coastguard Worker; CHECK: %[[Y:.*]] = load i64, i64* @y, align 8
27*9880d681SAndroid Build Coastguard Worker; CHECK: %[[YB:.*]] = icmp eq i64 %[[Y]], 0
28*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br i1
29*9880d681SAndroid Build Coastguard Worker; CHECK: br label
30*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %[[YB]]
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker  %x2 = alloca i8, align 1
33*9880d681SAndroid Build Coastguard Worker  %frombool1 = zext i1 %x to i8
34*9880d681SAndroid Build Coastguard Worker  store volatile i8 %frombool1, i8* %x2, align 1
35*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* @y, align 8
36*9880d681SAndroid Build Coastguard Worker  %tobool3 = icmp eq i64 %0, 0
37*9880d681SAndroid Build Coastguard Worker  br label %for.body
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Workerfor.body:
40*9880d681SAndroid Build Coastguard Worker  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
41*9880d681SAndroid Build Coastguard Worker  %x2.0. = load volatile i8, i8* %x2, align 1
42*9880d681SAndroid Build Coastguard Worker  %tobool2 = icmp eq i8 %x2.0., 0
43*9880d681SAndroid Build Coastguard Worker  br i1 %tobool2, label %for.inc, label %if.then
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Workerif.then:
46*9880d681SAndroid Build Coastguard Worker  br i1 %tobool3, label %if.else, label %if.then4
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Workerif.then4:
49*9880d681SAndroid Build Coastguard Worker  store volatile i32 %p, i32* @sink, align 4
50*9880d681SAndroid Build Coastguard Worker  br label %for.inc
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerif.else:
53*9880d681SAndroid Build Coastguard Worker  store volatile i32 %q, i32* @sink, align 4
54*9880d681SAndroid Build Coastguard Worker  br label %for.inc
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerfor.inc:
57*9880d681SAndroid Build Coastguard Worker  %inc = add nsw i32 %i.01, 1
58*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 %inc, 1
59*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Workerfor.end:
62*9880d681SAndroid Build Coastguard Worker  ret void
63*9880d681SAndroid Build Coastguard Worker}
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker; The same as above, but "y" is a function parameter instead of a global.
67*9880d681SAndroid Build Coastguard Worker; This shows that it is not enough to suppress hoisting of load instructions,
68*9880d681SAndroid Build Coastguard Worker; the actual problem is in the speculative branching.
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Workerdefine void @may_not_execute2(i1 zeroext %x, i1 zeroext %y, i32 %p, i32 %q) sanitize_memory {
71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @may_not_execute2(
72*9880d681SAndroid Build Coastguard Workerentry:
73*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br i1
74*9880d681SAndroid Build Coastguard Worker; CHECK: br label
75*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %y,
76*9880d681SAndroid Build Coastguard Worker  %x2 = alloca i8, align 1
77*9880d681SAndroid Build Coastguard Worker  %frombool2 = zext i1 %x to i8
78*9880d681SAndroid Build Coastguard Worker  store volatile i8 %frombool2, i8* %x2, align 1
79*9880d681SAndroid Build Coastguard Worker  br label %for.body
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Workerfor.body:
82*9880d681SAndroid Build Coastguard Worker  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
83*9880d681SAndroid Build Coastguard Worker  %x2.0. = load volatile i8, i8* %x2, align 1
84*9880d681SAndroid Build Coastguard Worker  %tobool3 = icmp eq i8 %x2.0., 0
85*9880d681SAndroid Build Coastguard Worker  br i1 %tobool3, label %for.inc, label %if.then
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Workerif.then:
88*9880d681SAndroid Build Coastguard Worker  br i1 %y, label %if.then5, label %if.else
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Workerif.then5:
91*9880d681SAndroid Build Coastguard Worker  store volatile i32 %p, i32* @sink, align 4
92*9880d681SAndroid Build Coastguard Worker  br label %for.inc
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Workerif.else:
95*9880d681SAndroid Build Coastguard Worker  store volatile i32 %q, i32* @sink, align 4
96*9880d681SAndroid Build Coastguard Worker  br label %for.inc
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Workerfor.inc:
99*9880d681SAndroid Build Coastguard Worker  %inc = add nsw i32 %i.01, 1
100*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 %inc, 1
101*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Workerfor.end:
104*9880d681SAndroid Build Coastguard Worker  ret void
105*9880d681SAndroid Build Coastguard Worker}
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker; The following is approximately:
109*9880d681SAndroid Build Coastguard Worker; void f(bool x, int p, int q) {
110*9880d681SAndroid Build Coastguard Worker;   volatile bool x2 = x;
111*9880d681SAndroid Build Coastguard Worker;   for (int i = 0; i < 1; ++i) {
112*9880d681SAndroid Build Coastguard Worker;     if (y)
113*9880d681SAndroid Build Coastguard Worker;       sink = p;
114*9880d681SAndroid Build Coastguard Worker;     else
115*9880d681SAndroid Build Coastguard Worker;       sink = q;
116*9880d681SAndroid Build Coastguard Worker;   }
117*9880d681SAndroid Build Coastguard Worker; }
118*9880d681SAndroid Build Coastguard Worker; "if (y)" is guaranteed to execute; the loop can be unswitched.
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerdefine void @must_execute(i1 zeroext %x, i32 %p, i32 %q) sanitize_memory {
121*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @must_execute(
122*9880d681SAndroid Build Coastguard Workerentry:
123*9880d681SAndroid Build Coastguard Worker; CHECK:       %[[Y:.*]] = load i64, i64* @y, align 8
124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %[[YB:.*]] = icmp eq i64 %[[Y]], 0
125*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  br i1 %[[YB]],
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker  %x2 = alloca i8, align 1
128*9880d681SAndroid Build Coastguard Worker  %frombool1 = zext i1 %x to i8
129*9880d681SAndroid Build Coastguard Worker  store volatile i8 %frombool1, i8* %x2, align 1
130*9880d681SAndroid Build Coastguard Worker  %0 = load i64, i64* @y, align 8
131*9880d681SAndroid Build Coastguard Worker  %tobool2 = icmp eq i64 %0, 0
132*9880d681SAndroid Build Coastguard Worker  br label %for.body
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Workerfor.body:
135*9880d681SAndroid Build Coastguard Worker  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
136*9880d681SAndroid Build Coastguard Worker  br i1 %tobool2, label %if.else, label %if.then
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Workerif.then:
139*9880d681SAndroid Build Coastguard Worker  store volatile i32 %p, i32* @sink, align 4
140*9880d681SAndroid Build Coastguard Worker  br label %for.inc
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Workerif.else:
143*9880d681SAndroid Build Coastguard Worker  store volatile i32 %q, i32* @sink, align 4
144*9880d681SAndroid Build Coastguard Worker  br label %for.inc
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Workerfor.inc:
147*9880d681SAndroid Build Coastguard Worker  %inc = add nsw i32 %i.01, 1
148*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 %inc, 1
149*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Workerfor.end:
152*9880d681SAndroid Build Coastguard Worker  ret void
153*9880d681SAndroid Build Coastguard Worker}
154