Skip to content

Commit 43d6991

Browse files
antoniofrighettonikic
authored andcommitted
[IR] Look through bitcast in hasFnAttribute()
A logic incompleteness may lead MemorySSA to be too conservative in its results. Specifically, when dealing with a call of kind `call i32 bitcast (i1 (i1)* @test to i32 (i32)*)(i32 %1)`, where the function `test` is declared with readonly attribute, the bitcast is not looked through, obscuring function attributes. Hence, some methods of CallBase (e.g., doesNotReadMemory) could provide suboptimal results. Differential Revision: https://reviews.llvm.org/D109888
1 parent 248342b commit 43d6991

File tree

5 files changed

+178
-69
lines changed

5 files changed

+178
-69
lines changed

llvm/lib/IR/Instructions.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,14 +349,26 @@ bool CallBase::paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
349349
}
350350

351351
bool CallBase::hasFnAttrOnCalledFunction(Attribute::AttrKind Kind) const {
352-
if (const Function *F = getCalledFunction())
352+
Value *V = getCalledOperand();
353+
if (auto *CE = dyn_cast<ConstantExpr>(V))
354+
if (CE->getOpcode() == BitCast)
355+
V = CE->getOperand(0);
356+
357+
if (auto *F = dyn_cast<Function>(V))
353358
return F->getAttributes().hasFnAttr(Kind);
359+
354360
return false;
355361
}
356362

357363
bool CallBase::hasFnAttrOnCalledFunction(StringRef Kind) const {
358-
if (const Function *F = getCalledFunction())
364+
Value *V = getCalledOperand();
365+
if (auto *CE = dyn_cast<ConstantExpr>(V))
366+
if (CE->getOpcode() == BitCast)
367+
V = CE->getOperand(0);
368+
369+
if (auto *F = dyn_cast<Function>(V))
359370
return F->getAttributes().hasFnAttr(Kind);
371+
360372
return false;
361373
}
362374

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s
2+
;
3+
; Ensures that MemorySSA leverages the ground truth of the function being called when wrapped in a bitcast.
4+
5+
declare i1 @opaque_true(i1) nounwind readonly
6+
7+
define i1 @foo(i32* %ptr, i1 %cond) {
8+
%cond_wide = zext i1 %cond to i32
9+
; CHECK: MemoryUse(liveOnEntry) MayAlias
10+
; CHECK-NEXT: call i32 bitcast
11+
%cond_hidden_wide = call i32 bitcast (i1 (i1)* @opaque_true to i32 (i32)*)(i32 %cond_wide)
12+
%cond_hidden = trunc i32 %cond_hidden_wide to i1
13+
ret i1 %cond_hidden
14+
}

llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,16 @@
3636
; FIXME we should recognize this as UB and make it an unreachable.
3737

3838
define dso_local i16 @foo(i16 %a) {
39-
; CHECK-LABEL: define {{[^@]+}}@foo
40-
; CHECK-SAME: (i16 [[A:%.*]]) {
41-
; CHECK-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16)*)(i16 [[A]])
42-
; CHECK-NEXT: ret i16 [[CALL]]
39+
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo
40+
; NOT_CGSCC_NPM-SAME: (i16 [[A:%.*]]) {
41+
; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16)*)(i16 [[A]])
42+
; NOT_CGSCC_NPM-NEXT: ret i16 [[CALL]]
43+
;
44+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
45+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
46+
; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
47+
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16)*)(i16 [[A]])
48+
; IS__CGSCC_NPM-NEXT: ret i16 [[CALL]]
4349
;
4450
%call = call i16 bitcast (i16 (i16, i16) * @bar to i16 (i16) *)(i16 %a)
4551
ret i16 %call
@@ -51,19 +57,30 @@ define internal i16 @bar(i16 %p1, i16 %p2) {
5157
; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR0:[0-9]+]] {
5258
; IS__TUNIT____-NEXT: ret i16 0
5359
;
54-
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
55-
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
56-
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR0:[0-9]+]] {
57-
; IS__CGSCC____-NEXT: ret i16 0
60+
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
61+
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar
62+
; IS__CGSCC_OPM-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR0:[0-9]+]] {
63+
; IS__CGSCC_OPM-NEXT: ret i16 0
64+
;
65+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
66+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar
67+
; IS__CGSCC_NPM-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR1:[0-9]+]] {
68+
; IS__CGSCC_NPM-NEXT: ret i16 0
5869
;
5970
ret i16 0
6071
}
6172

6273
define dso_local i16 @foo2(i16 %a) {
63-
; CHECK-LABEL: define {{[^@]+}}@foo2
64-
; CHECK-SAME: (i16 [[A:%.*]]) {
65-
; CHECK-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar2 to i16 (i16)*)(i16 [[A]])
66-
; CHECK-NEXT: ret i16 [[CALL]]
74+
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo2
75+
; NOT_CGSCC_NPM-SAME: (i16 [[A:%.*]]) {
76+
; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar2 to i16 (i16)*)(i16 [[A]])
77+
; NOT_CGSCC_NPM-NEXT: ret i16 [[CALL]]
78+
;
79+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
80+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo2
81+
; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]]) #[[ATTR0]] {
82+
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar2 to i16 (i16)*)(i16 [[A]])
83+
; IS__CGSCC_NPM-NEXT: ret i16 [[CALL]]
6784
;
6885
%call = call i16 bitcast (i16 (i16, i16) * @bar2 to i16 (i16) *)(i16 %a)
6986
ret i16 %call
@@ -76,11 +93,17 @@ define internal i16 @bar2(i16 %p1, i16 %p2) {
7693
; IS__TUNIT____-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
7794
; IS__TUNIT____-NEXT: ret i16 [[A]]
7895
;
79-
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
80-
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar2
81-
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR0]] {
82-
; IS__CGSCC____-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
83-
; IS__CGSCC____-NEXT: ret i16 [[A]]
96+
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
97+
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar2
98+
; IS__CGSCC_OPM-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR0]] {
99+
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
100+
; IS__CGSCC_OPM-NEXT: ret i16 [[A]]
101+
;
102+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
103+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar2
104+
; IS__CGSCC_NPM-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) #[[ATTR1]] {
105+
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
106+
; IS__CGSCC_NPM-NEXT: ret i16 [[A]]
84107
;
85108
%a = add i16 %p1, %p2
86109
ret i16 %a
@@ -93,11 +116,18 @@ define internal i16 @bar2(i16 %p1, i16 %p2) {
93116
; been provided),
94117

95118
define dso_local i16 @vararg_tests(i16 %a) {
96-
; CHECK-LABEL: define {{[^@]+}}@vararg_tests
97-
; CHECK-SAME: (i16 [[A:%.*]]) {
98-
; CHECK-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 noundef 7)
99-
; CHECK-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]]
100-
; CHECK-NEXT: ret i16 [[ADD]]
119+
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@vararg_tests
120+
; NOT_CGSCC_NPM-SAME: (i16 [[A:%.*]]) {
121+
; NOT_CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 noundef 7)
122+
; NOT_CGSCC_NPM-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]]
123+
; NOT_CGSCC_NPM-NEXT: ret i16 [[ADD]]
124+
;
125+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
126+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vararg_tests
127+
; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]]) #[[ATTR0]] {
128+
; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 noundef 7)
129+
; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]]
130+
; IS__CGSCC_NPM-NEXT: ret i16 [[ADD]]
101131
;
102132
%call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a)
103133
%call2 = call i16 bitcast (i16 (i16, i16, ...) * @vararg_no_prop to i16 (i16) *) (i16 7)
@@ -106,10 +136,15 @@ define dso_local i16 @vararg_tests(i16 %a) {
106136
}
107137

108138
define internal i16 @vararg_prop(i16 %p1, ...) {
109-
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
110-
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop
111-
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], ...) #[[ATTR0]] {
112-
; IS__CGSCC____-NEXT: ret i16 undef
139+
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
140+
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_prop
141+
; IS__CGSCC_OPM-SAME: (i16 [[P1:%.*]], ...) #[[ATTR0]] {
142+
; IS__CGSCC_OPM-NEXT: ret i16 undef
143+
;
144+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
145+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vararg_prop
146+
; IS__CGSCC_NPM-SAME: (i16 [[P1:%.*]], ...) #[[ATTR1]] {
147+
; IS__CGSCC_NPM-NEXT: ret i16 undef
113148
;
114149
ret i16 %p1
115150
}
@@ -120,16 +155,24 @@ define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) {
120155
; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
121156
; IS__TUNIT____-NEXT: ret i16 7
122157
;
123-
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
124-
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_no_prop
125-
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
126-
; IS__CGSCC____-NEXT: ret i16 7
158+
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
159+
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_no_prop
160+
; IS__CGSCC_OPM-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
161+
; IS__CGSCC_OPM-NEXT: ret i16 7
162+
;
163+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
164+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vararg_no_prop
165+
; IS__CGSCC_NPM-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR1]] {
166+
; IS__CGSCC_NPM-NEXT: ret i16 7
127167
;
128168
ret i16 %p1
129169
}
130170

131171
;.
132172
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
133173
;.
134-
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
174+
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
175+
;.
176+
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone }
177+
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
135178
;.

llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@
88
; argument type between the caller and callee.
99

1010
define dso_local i16 @foo(i16 %a) {
11-
; CHECK-LABEL: define {{[^@]+}}@foo
12-
; CHECK-SAME: (i16 [[A:%.*]]) {
13-
; CHECK-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16, i32)*)(i16 [[A]], i32 7)
14-
; CHECK-NEXT: ret i16 [[CALL]]
11+
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo
12+
; NOT_CGSCC_NPM-SAME: (i16 [[A:%.*]]) {
13+
; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16, i32)*)(i16 [[A]], i32 7)
14+
; NOT_CGSCC_NPM-NEXT: ret i16 [[CALL]]
15+
;
16+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
17+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
18+
; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
19+
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 bitcast (i16 (i16, i16)* @bar to i16 (i16, i32)*)(i16 [[A]], i32 7)
20+
; IS__CGSCC_NPM-NEXT: ret i16 [[CALL]]
1521
;
1622
%call = call i16 bitcast (i16 (i16, i16) * @bar to i16 (i16, i32) *)(i16 %a, i32 7)
1723
ret i16 %call
@@ -23,10 +29,15 @@ define internal i16 @bar(i16 %p1, i16 %p2) {
2329
; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]]) #[[ATTR0:[0-9]+]] {
2430
; IS__TUNIT____-NEXT: ret i16 [[P2]]
2531
;
26-
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
27-
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
28-
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]]) #[[ATTR0:[0-9]+]] {
29-
; IS__CGSCC____-NEXT: ret i16 [[P2]]
32+
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
33+
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar
34+
; IS__CGSCC_OPM-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]]) #[[ATTR0:[0-9]+]] {
35+
; IS__CGSCC_OPM-NEXT: ret i16 [[P2]]
36+
;
37+
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
38+
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar
39+
; IS__CGSCC_NPM-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]]) #[[ATTR1:[0-9]+]] {
40+
; IS__CGSCC_NPM-NEXT: ret i16 [[P2]]
3041
;
3142
ret i16 %p2
3243
}
@@ -35,5 +46,8 @@ define internal i16 @bar(i16 %p1, i16 %p2) {
3546
;.
3647
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
3748
;.
38-
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
49+
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
50+
;.
51+
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone }
52+
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
3953
;.

llvm/test/Transforms/Attributor/liveness.ll

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,33 +2473,59 @@ indirectgoto: ; preds = %lab0, %entry
24732473
@e = global %struct.a* null
24742474

24752475
define i32 @main() {
2476-
; CHECK-LABEL: define {{[^@]+}}@main() {
2477-
; CHECK-NEXT: entry:
2478-
; CHECK-NEXT: [[F:%.*]] = alloca i32, align 4
2479-
; CHECK-NEXT: br label [[FOR_COND_0:%.*]]
2480-
; CHECK: for.cond.0:
2481-
; CHECK-NEXT: [[G_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_0:%.*]] ]
2482-
; CHECK-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[G_0]], 100
2483-
; CHECK-NEXT: br i1 [[CMP_0]], label [[FOR_BODY_0]], label [[FOR_END_0:%.*]]
2484-
; CHECK: for.body.0:
2485-
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1
2486-
; CHECK-NEXT: br label [[FOR_COND_0]]
2487-
; CHECK: for.end.0:
2488-
; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 noundef 8)
2489-
; CHECK-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8
2490-
; CHECK-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a**
2491-
; CHECK-NEXT: store %struct.a* null, %struct.a** [[B]], align 8
2492-
; CHECK-NEXT: br label [[FOR_COND_1:%.*]]
2493-
; CHECK: for.cond.1:
2494-
; CHECK-NEXT: [[G_1:%.*]] = phi i32 [ 0, [[FOR_END_0]] ], [ [[INC6:%.*]], [[FOR_BODY_1:%.*]] ]
2495-
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[G_1]], 100
2496-
; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_1]], label [[FOR_END_1:%.*]]
2497-
; CHECK: for.body.1:
2498-
; CHECK-NEXT: [[CALL4:%.*]] = call i32 (i32*, ...) bitcast (i32 (i32)* @h to i32 (i32*, ...)*)(i32* nonnull [[F]])
2499-
; CHECK-NEXT: [[INC6]] = add nuw nsw i32 [[G_1]], 1
2500-
; CHECK-NEXT: br label [[FOR_COND_1]]
2501-
; CHECK: for.end.1:
2502-
; CHECK-NEXT: ret i32 0
2476+
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@main() {
2477+
; NOT_CGSCC_NPM-NEXT: entry:
2478+
; NOT_CGSCC_NPM-NEXT: [[F:%.*]] = alloca i32, align 4
2479+
; NOT_CGSCC_NPM-NEXT: br label [[FOR_COND_0:%.*]]
2480+
; NOT_CGSCC_NPM: for.cond.0:
2481+
; NOT_CGSCC_NPM-NEXT: [[G_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_0:%.*]] ]
2482+
; NOT_CGSCC_NPM-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[G_0]], 100
2483+
; NOT_CGSCC_NPM-NEXT: br i1 [[CMP_0]], label [[FOR_BODY_0]], label [[FOR_END_0:%.*]]
2484+
; NOT_CGSCC_NPM: for.body.0:
2485+
; NOT_CGSCC_NPM-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1
2486+
; NOT_CGSCC_NPM-NEXT: br label [[FOR_COND_0]]
2487+
; NOT_CGSCC_NPM: for.end.0:
2488+
; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 noundef 8)
2489+
; NOT_CGSCC_NPM-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8
2490+
; NOT_CGSCC_NPM-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a**
2491+
; NOT_CGSCC_NPM-NEXT: store %struct.a* null, %struct.a** [[B]], align 8
2492+
; NOT_CGSCC_NPM-NEXT: br label [[FOR_COND_1:%.*]]
2493+
; NOT_CGSCC_NPM: for.cond.1:
2494+
; NOT_CGSCC_NPM-NEXT: [[G_1:%.*]] = phi i32 [ 0, [[FOR_END_0]] ], [ [[INC6:%.*]], [[FOR_BODY_1:%.*]] ]
2495+
; NOT_CGSCC_NPM-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[G_1]], 100
2496+
; NOT_CGSCC_NPM-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_1]], label [[FOR_END_1:%.*]]
2497+
; NOT_CGSCC_NPM: for.body.1:
2498+
; NOT_CGSCC_NPM-NEXT: [[CALL4:%.*]] = call i32 (i32*, ...) bitcast (i32 (i32)* @h to i32 (i32*, ...)*)(i32* nonnull [[F]])
2499+
; NOT_CGSCC_NPM-NEXT: [[INC6]] = add nuw nsw i32 [[G_1]], 1
2500+
; NOT_CGSCC_NPM-NEXT: br label [[FOR_COND_1]]
2501+
; NOT_CGSCC_NPM: for.end.1:
2502+
; NOT_CGSCC_NPM-NEXT: ret i32 0
2503+
;
2504+
; IS__CGSCC____-LABEL: define {{[^@]+}}@main() {
2505+
; IS__CGSCC____-NEXT: entry:
2506+
; IS__CGSCC____-NEXT: br label [[FOR_COND_0:%.*]]
2507+
; IS__CGSCC____: for.cond.0:
2508+
; IS__CGSCC____-NEXT: [[G_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY_0:%.*]] ]
2509+
; IS__CGSCC____-NEXT: [[CMP_0:%.*]] = icmp ult i32 [[G_0]], 100
2510+
; IS__CGSCC____-NEXT: br i1 [[CMP_0]], label [[FOR_BODY_0]], label [[FOR_END_0:%.*]]
2511+
; IS__CGSCC____: for.body.0:
2512+
; IS__CGSCC____-NEXT: [[INC]] = add nuw nsw i32 [[G_0]], 1
2513+
; IS__CGSCC____-NEXT: br label [[FOR_COND_0]]
2514+
; IS__CGSCC____: for.end.0:
2515+
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 noundef 8)
2516+
; IS__CGSCC____-NEXT: store i8* [[CALL]], i8** bitcast (%struct.a** @e to i8**), align 8
2517+
; IS__CGSCC____-NEXT: [[B:%.*]] = bitcast i8* [[CALL]] to %struct.a**
2518+
; IS__CGSCC____-NEXT: store %struct.a* null, %struct.a** [[B]], align 8
2519+
; IS__CGSCC____-NEXT: br label [[FOR_COND_1:%.*]]
2520+
; IS__CGSCC____: for.cond.1:
2521+
; IS__CGSCC____-NEXT: [[G_1:%.*]] = phi i32 [ 0, [[FOR_END_0]] ], [ [[INC6:%.*]], [[FOR_BODY_1:%.*]] ]
2522+
; IS__CGSCC____-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[G_1]], 100
2523+
; IS__CGSCC____-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_1]], label [[FOR_END_1:%.*]]
2524+
; IS__CGSCC____: for.body.1:
2525+
; IS__CGSCC____-NEXT: [[INC6]] = add nuw nsw i32 [[G_1]], 1
2526+
; IS__CGSCC____-NEXT: br label [[FOR_COND_1]]
2527+
; IS__CGSCC____: for.end.1:
2528+
; IS__CGSCC____-NEXT: ret i32 0
25032529
;
25042530
entry:
25052531
%f = alloca i32

0 commit comments

Comments
 (0)