xref: /llvm-project/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll (revision cd3a4c31bc9694d160de54c6a4daa53e152cb463)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
4;
5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
6
7%struct.S = type { i32, double, ptr, i32 }
8
9;    struct S {
10;      int a;
11;      double b;
12;      struct S* c;
13;      int written;
14;    };
15;
16;    static const struct S GlobalS = {42, 3.14, 0};
17;
18;    int testOneFieldGlobalS() {
19;      int r = 0;
20;      if (GlobalS.a != 42)
21;        r += 1;
22;      if (GlobalS.b == 3.14)
23;        r += 2;
24;      if (GlobalS.c)
25;        r += 4;
26;      return r;
27;    }
28;
29@GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8
30
31declare void @harmless_use(ptr nocapture readonly) nofree norecurse nosync nounwind readnone willreturn nocallback
32
33;.
34; CHECK: @GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8
35;.
36define i32 @testOneFieldGlobalS(i32 %cmpx) {
37; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
38; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS
39; CHECK-SAME: (i32 [[CMPX:%.*]]) #[[ATTR1:[0-9]+]] {
40; CHECK-NEXT:  entry:
41; CHECK-NEXT:    [[RMW:%.*]] = atomicrmw add ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @GlobalS, i32 0, i32 3), i32 1 monotonic, align 4
42; CHECK-NEXT:    [[CXI:%.*]] = cmpxchg ptr getelementptr inbounds ([[STRUCT_S]], ptr @GlobalS, i32 0, i32 3), i32 [[CMPX]], i32 7 acq_rel monotonic, align 4
43; CHECK-NEXT:    br label [[IF_END:%.*]]
44; CHECK:       if.then:
45; CHECK-NEXT:    unreachable
46; CHECK:       if.end:
47; CHECK-NEXT:    br label [[IF_THEN2:%.*]]
48; CHECK:       if.then2:
49; CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 0, 2
50; CHECK-NEXT:    br label [[IF_END4:%.*]]
51; CHECK:       if.end4:
52; CHECK-NEXT:    br label [[IF_END7:%.*]]
53; CHECK:       if.then5:
54; CHECK-NEXT:    unreachable
55; CHECK:       if.end7:
56; CHECK-NEXT:    ret i32 2
57;
58entry:
59  %i = load i32, ptr @GlobalS, align 8
60  call void @harmless_use(ptr @GlobalS)
61  %rmw = atomicrmw add ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 3), i32 1 monotonic, align 4
62  %cxi = cmpxchg ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 3), i32 %cmpx, i32 7 acq_rel monotonic
63  %cmp = icmp ne i32 %i, 42
64  br i1 %cmp, label %if.then, label %if.end
65
66if.then:                                          ; preds = %entry
67  %add = add nsw i32 0, 1
68  br label %if.end
69
70if.end:                                           ; preds = %if.then, %entry
71  %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ]
72  %i1 = load double, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8
73  %cmp1 = fcmp oeq double %i1, 3.140000e+00
74  br i1 %cmp1, label %if.then2, label %if.end4
75
76if.then2:                                         ; preds = %if.end
77  %add3 = add nsw i32 %r.0, 2
78  br label %if.end4
79
80if.end4:                                          ; preds = %if.then2, %if.end
81  %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ]
82  %i2 = load ptr, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8
83  %tobool = icmp ne ptr %i2, null
84  br i1 %tobool, label %if.then5, label %if.end7
85
86if.then5:                                         ; preds = %if.end4
87  %add6 = add nsw i32 %r.1, 4
88  br label %if.end7
89
90if.end7:                                          ; preds = %if.then5, %if.end4
91  %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ]
92  ret i32 %r.2
93}
94
95define i32 @testOneFieldGlobalS_type_mismatch() {
96; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
97; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_type_mismatch
98; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
99; CHECK-NEXT:  entry:
100; CHECK-NEXT:    br label [[IF_THEN:%.*]]
101; CHECK:       if.then:
102; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, 1
103; CHECK-NEXT:    br label [[IF_END:%.*]]
104; CHECK:       if.end:
105; CHECK-NEXT:    br label [[IF_END4:%.*]]
106; CHECK:       if.then2:
107; CHECK-NEXT:    unreachable
108; CHECK:       if.end4:
109; CHECK-NEXT:    br label [[IF_END7:%.*]]
110; CHECK:       if.then5:
111; CHECK-NEXT:    unreachable
112; CHECK:       if.end7:
113; CHECK-NEXT:    ret i32 1
114;
115entry:
116  %i = load double, ptr @GlobalS, align 8
117  %ic = fptosi double %i to i32
118  %cmp = icmp ne i32 %ic, 42
119  br i1 %cmp, label %if.then, label %if.end
120
121if.then:                                          ; preds = %entry
122  %add = add nsw i32 0, 1
123  br label %if.end
124
125if.end:                                           ; preds = %if.then, %entry
126  %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ]
127  %i1 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 1), align 8
128  %i1c = sitofp i64 %i1 to double
129  %cmp1 = fcmp oeq double %i1c, 3.140000e+00
130  br i1 %cmp1, label %if.then2, label %if.end4
131
132if.then2:                                         ; preds = %if.end
133  %add3 = add nsw i32 %r.0, 2
134  br label %if.end4
135
136if.end4:                                          ; preds = %if.then2, %if.end
137  %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ]
138  %i2 = load i64, ptr getelementptr inbounds (%struct.S, ptr @GlobalS, i32 0, i32 2), align 8
139  %i2c = inttoptr i64 %i2 to ptr
140  %tobool = icmp ne ptr %i2c, null
141  br i1 %tobool, label %if.then5, label %if.end7
142
143if.then5:                                         ; preds = %if.end4
144  %add6 = add nsw i32 %r.1, 4
145  br label %if.end7
146
147if.end7:                                          ; preds = %if.then5, %if.end4
148  %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ]
149  ret i32 %r.2
150}
151
152define i32 @testOneFieldGlobalS_byte_offset_wrong() {
153; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
154; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_byte_offset_wrong
155; CHECK-SAME: () #[[ATTR2]] {
156; CHECK-NEXT:  entry:
157; CHECK-NEXT:    br label [[IF_THEN:%.*]]
158; CHECK:       if.then:
159; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 0, 1
160; CHECK-NEXT:    br label [[IF_END:%.*]]
161; CHECK:       if.end:
162; CHECK-NEXT:    [[I1:%.*]] = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8
163; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oeq double [[I1]], 3.140000e+00
164; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]]
165; CHECK:       if.then2:
166; CHECK-NEXT:    [[ADD3:%.*]] = add nsw i32 1, 2
167; CHECK-NEXT:    br label [[IF_END4]]
168; CHECK:       if.end4:
169; CHECK-NEXT:    [[R_1:%.*]] = phi i32 [ [[ADD3]], [[IF_THEN2]] ], [ 1, [[IF_END]] ]
170; CHECK-NEXT:    br label [[IF_END7:%.*]]
171; CHECK:       if.then5:
172; CHECK-NEXT:    unreachable
173; CHECK:       if.end7:
174; CHECK-NEXT:    ret i32 [[R_1]]
175;
176entry:
177  %i = load i32, ptr getelementptr (i32, ptr @GlobalS, i32 1), align 8
178  %cmp = icmp ne i32 %i, 42
179  br i1 %cmp, label %if.then, label %if.end
180
181if.then:                                          ; preds = %entry
182  %add = add nsw i32 0, 1
183  br label %if.end
184
185if.end:                                           ; preds = %if.then, %entry
186  %r.0 = phi i32 [ %add, %if.then ], [ 0, %entry ]
187  %i1 = load double, ptr getelementptr (double, ptr @GlobalS, i32 3), align 8
188  %cmp1 = fcmp oeq double %i1, 3.140000e+00
189  br i1 %cmp1, label %if.then2, label %if.end4
190
191if.then2:                                         ; preds = %if.end
192  %add3 = add nsw i32 %r.0, 2
193  br label %if.end4
194
195if.end4:                                          ; preds = %if.then2, %if.end
196  %r.1 = phi i32 [ %add3, %if.then2 ], [ %r.0, %if.end ]
197  %i2 = load ptr, ptr getelementptr (ptr, ptr @GlobalS, i32 2), align 8
198  %tobool = icmp ne ptr %i2, null
199  br i1 %tobool, label %if.then5, label %if.end7
200
201if.then5:                                         ; preds = %if.end4
202  %add6 = add nsw i32 %r.1, 4
203  br label %if.end7
204
205if.end7:                                          ; preds = %if.then5, %if.end4
206  %r.2 = phi i32 [ %add6, %if.then5 ], [ %r.1, %if.end4 ]
207  ret i32 %r.2
208}
209;.
210; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind willreturn memory(none) }
211; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(none) }
212; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
213;.
214;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
215; CGSCC: {{.*}}
216; TUNIT: {{.*}}
217