Skip to content

Commit 210ac6f

Browse files
Fix bugs
1 parent 6e36f63 commit 210ac6f

File tree

5 files changed

+176
-50
lines changed

5 files changed

+176
-50
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,27 +1618,39 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
16181618

16191619
auto *TI = BB->getTerminator();
16201620

1621-
SmallVector<BasicBlock *> SuccessorBlocks;
1622-
for (auto *Succ : successors(BB))
1623-
SuccessorBlocks.push_back(Succ);
1621+
SmallVector<BasicBlock *, 8> SuccessorBBs;
1622+
for (auto *Succ : successors(BB)) {
1623+
BasicBlock::iterator SuccItr = Succ->begin();
1624+
// If we find an unreachable instruction at the beginning of a basic block,
1625+
// we can still hoist instructions from the rest of the basic blocks.
1626+
if (isa<UnreachableInst>(*SuccItr))
1627+
continue;
1628+
SuccessorBBs.push_back(Succ);
1629+
}
16241630

1625-
// Sort successor blocks based on the number of instructions.
1626-
// This is because we always want to iterate over instructions
1627-
// of the smallest block.
1628-
llvm::stable_sort(SuccessorBlocks, [](BasicBlock *BB1, BasicBlock *BB2) {
1629-
return BB1->sizeWithoutDebug() < BB2->sizeWithoutDebug();
1630-
});
1631+
// Find the smallest BB because we always want to iterate over instructions
1632+
// of the smallest Successor.
1633+
auto *SmallestBB = *std::min_element(SuccessorBBs.begin(), SuccessorBBs.end(),
1634+
[](BasicBlock *BB1, BasicBlock *BB2) {
1635+
return BB1->size() < BB2->size();
1636+
});
1637+
std::iter_swap(
1638+
SuccessorBBs.begin(),
1639+
std::find(SuccessorBBs.begin(), SuccessorBBs.end(), SmallestBB));
16311640

16321641
// The second of pair is a SkipFlags bitmask.
16331642
using SuccIterPair = std::pair<BasicBlock::iterator, unsigned>;
16341643
SmallVector<SuccIterPair, 8> SuccIterPairs;
1635-
for (auto *Succ : SuccessorBlocks) {
1644+
for (auto *Succ : SuccessorBBs) {
16361645
BasicBlock::iterator SuccItr = Succ->begin();
16371646
if (isa<PHINode>(*SuccItr))
16381647
return false;
16391648
SuccIterPairs.push_back(SuccIterPair(SuccItr, 0));
16401649
}
16411650

1651+
if (SuccIterPairs.size() < 2)
1652+
return false;
1653+
16421654
// Check if only hoisting terminators is allowed. This does not add new
16431655
// instructions to the hoist location.
16441656
if (EqTermsOnly) {
@@ -1656,14 +1668,6 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
16561668
// many instructions we skip, serving as a compilation time control as well as
16571669
// preventing excessive increase of life ranges.
16581670
unsigned NumSkipped = 0;
1659-
// If we find an unreachable instruction at the beginning of a basic block, we
1660-
// can still hoist instructions from the rest of the basic blocks.
1661-
if (SuccIterPairs.size() > 2) {
1662-
erase_if(SuccIterPairs,
1663-
[](const auto &Pair) { return isa<UnreachableInst>(Pair.first); });
1664-
if (SuccIterPairs.size() < 2)
1665-
return false;
1666-
}
16671671

16681672
bool Changed = false;
16691673
auto *SuccIterPairBegin = SuccIterPairs.begin();
@@ -1697,14 +1701,25 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
16971701
auto OtherSuccIterPairRange =
16981702
iterator_range(SuccIterPairBegin, SuccIterPairs.end());
16991703
Instruction *I1 = &*BB1ItrPair.first;
1704+
1705+
// Skip debug info if it is not identical.
1706+
bool IdenticalDebugs = all_of(OtherSuccIterRange, [I1](auto &Iter) {
1707+
Instruction *I2 = &*Iter;
1708+
return I1->isIdenticalToWhenDefined(I2);
1709+
});
1710+
if (!IdenticalDebugs) {
1711+
while (isa<DbgInfoIntrinsic>(I1))
1712+
I1 = &*++BB1ItrPair.first;
1713+
}
1714+
17001715
bool HasIdenticalInst = true;
17011716

17021717
// Check if there are identical instructions in all other successors
17031718
for (auto &map : OtherSuccessorsHash) {
17041719
Instruction *I2 = map[getHash(I1)].first;
17051720
// We might face with same hash values for different instructions.
17061721
// If that happens, ignore the instruction.
1707-
if (!I2 || !I1->isIdenticalTo(I2)) {
1722+
if (!I2 || !I1->isIdenticalToWhenDefined(I2)) {
17081723
HasIdenticalInst = false;
17091724
break;
17101725
}
@@ -1720,7 +1735,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
17201735
SuccIterPair.second |= skippedInstrFlags(I);
17211736
}
17221737
}
1723-
NumSkipped++;
1738+
++NumSkipped;
17241739
if (I1->isTerminator())
17251740
return Changed;
17261741
++BB1ItrPair.first;
@@ -1733,7 +1748,7 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
17331748
OtherInsts.push_back(&*(SuccIterPair.first));
17341749
} else {
17351750
for (auto &map : OtherSuccessorsHash)
1736-
OtherInstrs.push_back(map[getHash(I1)].first);
1751+
OtherInsts.push_back(map[getHash(I1)].first);
17371752
}
17381753

17391754
// If we are hoisting the terminator instruction, don't move one (making a
@@ -1810,13 +1825,38 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
18101825
for (auto &map : OtherSuccessorsHash) {
18111826
Instruction *I2 = map[getHash(I1)].first;
18121827
assert(I2 != I1);
1813-
if (!I2->use_empty())
1828+
// Update hashcode of all instructions using I2
1829+
if (!I2->use_empty()) {
1830+
SmallVector<llvm::hash_code, 8> PrevHashCodes;
1831+
SmallVector<llvm::Instruction *, 8> PrevUsers;
1832+
// Once the uses of I1 are replaced, the hash value computed for
1833+
// those users are not valid anymore so we gather users and then
1834+
// recompute the hash codes for them. We need to do this only for
1835+
// the instructions located in the same block as I2 because we
1836+
// initially only hashed those instructions.
1837+
for (auto *user : I2->users()) {
1838+
if (auto *I = dyn_cast<Instruction>(user)) {
1839+
if (I->getParent() != I2->getParent())
1840+
continue;
1841+
PrevHashCodes.push_back(getHash(I));
1842+
PrevUsers.push_back(I);
1843+
}
1844+
}
18141845
I2->replaceAllUsesWith(I1);
1846+
unsigned index = 0;
1847+
for (auto &PrevHash : PrevHashCodes) {
1848+
auto NewHash = getHash(PrevUsers[index]);
1849+
map.insert({NewHash, map[PrevHash]});
1850+
map.erase(PrevHash);
1851+
index++;
1852+
}
1853+
}
18151854
I1->andIRFlags(I2);
18161855
combineMetadataForCSE(I1, I2, true);
18171856
// I1 and I2 are being combined into a single instruction. Its debug
18181857
// location is the merged locations of the original instructions.
18191858
I1->applyMergedLocation(I1->getDebugLoc(), I2->getDebugLoc());
1859+
map.erase(getHash(I1));
18201860
I2->eraseFromParent();
18211861
}
18221862
}
@@ -1832,10 +1872,11 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(BasicBlock *BB,
18321872
// We are about to skip over a pair of non-identical instructions. Record
18331873
// if any have characteristics that would prevent reordering instructions
18341874
// across them.
1875+
BB1ItrPair.first++;
18351876
SkipFlagsBB1 |= skippedInstrFlags(I1);
18361877
if (SameLevelHoist) {
18371878
for (auto &SuccIterPair : OtherSuccIterPairRange) { // update flags
1838-
Instruction *I = &*SuccIterPair.first;
1879+
Instruction *I = &*SuccIterPair.first++;
18391880
SuccIterPair.second |= skippedInstrFlags(I);
18401881
}
18411882
}
@@ -1857,11 +1898,8 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
18571898
// Use only for an if statement.
18581899
auto *I2 = *OtherSuccTIs.begin();
18591900
auto *BB2 = I2->getParent();
1860-
if (BI) {
1901+
if (BI)
18611902
assert(OtherSuccTIs.size() == 1);
1862-
assert(BI->getSuccessor(0) == I1->getParent());
1863-
assert(BI->getSuccessor(1) == I2->getParent());
1864-
}
18651903

18661904
// In the case of an if statement, we try to hoist an invoke.
18671905
// FIXME: Can we define a safety predicate for CallBr?
@@ -1881,6 +1919,7 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
18811919
Value *BB2V = PN.getIncomingValueForBlock(OtherSuccTI->getParent());
18821920
if (BB1V == BB2V)
18831921
continue;
1922+
18841923
// In the case of an if statement, check for
18851924
// passingValueIsAlwaysUndefined here because we would rather eliminate
18861925
// undefined control flow then converting it to a select.
@@ -1952,16 +1991,20 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
19521991
}
19531992
}
19541993
}
1994+
19551995
SmallVector<DominatorTree::UpdateType, 4> Updates;
1996+
19561997
// Update any PHI nodes in our new successors.
19571998
for (BasicBlock *Succ : successors(BB1)) {
19581999
AddPredecessorToBlock(Succ, TIParent, BB1);
19592000
if (DTU)
19602001
Updates.push_back({DominatorTree::Insert, TIParent, Succ});
19612002
}
2003+
19622004
if (DTU)
19632005
for (BasicBlock *Succ : successors(TI))
19642006
Updates.push_back({DominatorTree::Delete, TIParent, Succ});
2007+
19652008
EraseTerminatorAndDCECond(TI);
19662009
if (DTU)
19672010
DTU->applyUpdates(Updates);
@@ -3713,7 +3756,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
37133756
// Change the PHI node into a select instruction.
37143757
Value *TrueVal = PN->getIncomingValueForBlock(IfTrue);
37153758
Value *FalseVal = PN->getIncomingValueForBlock(IfFalse);
3716-
3759+
37173760
Value *Sel = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI);
37183761
PN->replaceAllUsesWith(Sel);
37193762
Sel->takeName(PN);

llvm/test/CodeGen/ARM/aes-erratum-fix.ll

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -314,16 +314,15 @@ define arm_aapcs_vfpcc void @aese_set8_cond_via_ptr(i1 zeroext %0, ptr %1, <16 x
314314
; CHECK-FIX-LABEL: aese_set8_cond_via_ptr:
315315
; CHECK-FIX: @ %bb.0:
316316
; CHECK-FIX-NEXT: vorr q0, q0, q0
317+
; CHECK-FIX-NEXT: vld1.64 {d16, d17}, [r2]
317318
; CHECK-FIX-NEXT: cmp r0, #0
318319
; CHECK-FIX-NEXT: beq .LBB12_2
319320
; CHECK-FIX-NEXT: @ %bb.1:
320-
; CHECK-FIX-NEXT: vld1.64 {d16, d17}, [r2]
321321
; CHECK-FIX-NEXT: vld1.8 {d16[0]}, [r1]
322322
; CHECK-FIX-NEXT: cmp r0, #0
323323
; CHECK-FIX-NEXT: bne .LBB12_3
324324
; CHECK-FIX-NEXT: b .LBB12_4
325325
; CHECK-FIX-NEXT: .LBB12_2:
326-
; CHECK-FIX-NEXT: vld1.64 {d16, d17}, [r2]
327326
; CHECK-FIX-NEXT: cmp r0, #0
328327
; CHECK-FIX-NEXT: beq .LBB12_4
329328
; CHECK-FIX-NEXT: .LBB12_3:
@@ -3205,23 +3204,18 @@ define arm_aapcs_vfpcc void @aesd_set64_via_val(i64 %0, <16 x i8> %1, ptr %2) no
32053204
define arm_aapcs_vfpcc void @aesd_set64_cond_via_ptr(i1 zeroext %0, ptr %1, <16 x i8> %2, ptr %3) nounwind {
32063205
; CHECK-FIX-NOSCHED-LABEL: aesd_set64_cond_via_ptr:
32073206
; CHECK-FIX-NOSCHED: @ %bb.0:
3208-
; CHECK-FIX-NOSCHED-NEXT: cmp r0, #0
3209-
; CHECK-FIX-NOSCHED-NEXT: beq .LBB76_2
3210-
; CHECK-FIX-NOSCHED-NEXT: @ %bb.1:
3211-
; CHECK-FIX-NOSCHED-NEXT: vld1.64 {d16, d17}, [r2]
3212-
; CHECK-FIX-NOSCHED-NEXT: vldr d16, [r1]
3213-
; CHECK-FIX-NOSCHED-NEXT: b .LBB76_3
3214-
; CHECK-FIX-NOSCHED-NEXT: .LBB76_2:
32153207
; CHECK-FIX-NOSCHED-NEXT: vld1.64 {d16, d17}, [r2]
3216-
; CHECK-FIX-NOSCHED-NEXT: .LBB76_3:
3208+
; CHECK-FIX-NOSCHED-NEXT: cmp r0, #0
3209+
; CHECK-FIX-NOSCHED-NEXT: vldrne d16, [r1]
3210+
; CHECK-FIX-NOSCHED-NEXT: vorr q8, q8, q8
32173211
; CHECK-FIX-NOSCHED-NEXT: cmp r0, #0
32183212
; CHECK-FIX-NOSCHED-NEXT: vldrne d0, [r1]
32193213
; CHECK-FIX-NOSCHED-NEXT: vorr q0, q0, q0
32203214
; CHECK-FIX-NOSCHED-NEXT: aesd.8 q8, q0
32213215
; CHECK-FIX-NOSCHED-NEXT: aesimc.8 q8, q8
32223216
; CHECK-FIX-NOSCHED-NEXT: vst1.64 {d16, d17}, [r2]
32233217
; CHECK-FIX-NOSCHED-NEXT: bx lr
3224-
;
3218+
32253219
; CHECK-CORTEX-FIX-LABEL: aesd_set64_cond_via_ptr:
32263220
; CHECK-CORTEX-FIX: @ %bb.0:
32273221
; CHECK-CORTEX-FIX-NEXT: cmp r0, #0
@@ -4096,19 +4090,15 @@ define arm_aapcs_vfpcc void @aesd_setf32_cond_via_ptr(i1 zeroext %0, ptr %1, <16
40964090
; CHECK-FIX-LABEL: aesd_setf32_cond_via_ptr:
40974091
; CHECK-FIX: @ %bb.0:
40984092
; CHECK-FIX-NEXT: vorr q0, q0, q0
4093+
; CHECK-FIX-NEXT: vld1.64 {d16, d17}, [r2]
40994094
; CHECK-FIX-NEXT: cmp r0, #0
41004095
; CHECK-FIX-NEXT: beq .LBB88_2
41014096
; CHECK-FIX-NEXT: @ %bb.1:
4102-
; CHECK-FIX-NEXT: vld1.64 {d16, d17}, [r2]
41034097
; CHECK-FIX-NEXT: vld1.32 {d16[0]}, [r1:32]
4104-
; CHECK-FIX-NEXT: cmp r0, #0
4105-
; CHECK-FIX-NEXT: bne .LBB88_3
4106-
; CHECK-FIX-NEXT: b .LBB88_4
41074098
; CHECK-FIX-NEXT: .LBB88_2:
4108-
; CHECK-FIX-NEXT: vld1.64 {d16, d17}, [r2]
41094099
; CHECK-FIX-NEXT: cmp r0, #0
41104100
; CHECK-FIX-NEXT: beq .LBB88_4
4111-
; CHECK-FIX-NEXT: .LBB88_3:
4101+
; CHECK-FIX-NEXT: @ %bb.3:
41124102
; CHECK-FIX-NEXT: vld1.32 {d0[0]}, [r1:32]
41134103
; CHECK-FIX-NEXT: .LBB88_4:
41144104
; CHECK-FIX-NEXT: aesd.8 q8, q0

llvm/test/CodeGen/Thumb2/mve-memtp-branch.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ define i32 @a(i8 zeroext %b, ptr nocapture readonly %c, ptr nocapture readonly %
1111
; CHECK: @ %bb.0: @ %entry
1212
; CHECK-NEXT: .save {r4, r5, r7, lr}
1313
; CHECK-NEXT: push {r4, r5, r7, lr}
14-
; CHECK-NEXT: cmp r0, #2
15-
; CHECK-NEXT: bls.w .LBB0_12
14+
; CHECK-NEXT: cmp r0, #3
15+
; CHECK-NEXT: blo.w .LBB0_12
1616
; CHECK-NEXT: @ %bb.1: @ %for.body.us.preheader
1717
; CHECK-NEXT: movw r5, :lower16:arr_183
1818
; CHECK-NEXT: movs r3, #0
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
; opt -passes='default<O3>' -S --mtriple=aarch64-linux-gnu --mcpu=a64fx < %s | FileCheck %s
2+
3+
; Hoist identical instructions from successor blocks even if
4+
; they are not located at the same level. This could help generate
5+
; more compact vectorized code.
6+
; More info can be found at https://github.com/llvm/llvm-project/issues/68395.
7+
8+
9+
define void @hoist_then_vectorize(ptr %a, ptr %b, ptr %c, ptr %d, i32 %N){
10+
; CHECK-LABEL: @hoist_then_vectorize(
11+
; CHECK-NEXT: iter.check:
12+
; CHECK-NEXT: [[VSCALE:%.*]] = tail call i64 @llvm.vscale.i64()
13+
; CHECK-NEXT: [[SHIFT:%.*]] = shl i64 [[VSCALE:%.*]], 1
14+
; CHECK-NEXT: [[MIN_ITR:%.*]] = icmp ugt i64 [[SHIFT:%.*]], 20
15+
; CHECK-NEXT: br i1 [[MIN_ITR:%.*]], label [[FOR_BODY_PREHEADER:%.*]], label [[VECTOR_MAIN_LOOP_ITR_CHECK:%.*]]
16+
; CHECK: vector.main.loop.iter.check:
17+
; CHECK-NEXT: [[VSCALE2:%.*]] = tail call i64 @llvm.vscale.i64()
18+
; CHECK-NEXT: [[SHIFT2:%.*]] = shl i64 [[VSCALE2:%.*]], 2
19+
; CHECK-NEXT: [[MIN_ITR2:%.*]] = icmp ugt i64 [[SHIFT2:%.*]], 20
20+
; CHECK-NEXT: br i1 [[MIN_ITR2:%.*]], label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
21+
; CHECK: vector.ph:
22+
; CHECK-NEXT: [[VSCALE3:%.*]] = tail call i64 @llvm.vscale.i64()
23+
; CHECK-NEXT: [[SHIFT3:%.*]] = shl i64 [[VSCALE3:%.*]], 2
24+
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 20, [[SHIFT3:%.*]]
25+
; CHECK-NEXT: [[N_VEC:%.*]] = sub nuw nsw i64 20, [[N_MOD_VF:%.*]]
26+
; CHECK-NEXT: [[VSCALE4:%.*]] = tail call i64 @llvm.vscale.i64()
27+
; CHECK-NEXT: [[SHIFT4:%.*]] = shl i64 [[VSCALE4:%.*]], 2
28+
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
29+
; CHECK: vector.body:
30+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY:%.*]] ]
31+
; CHECK-NEXT: [[GEP_D:%.*]] = getelementptr inbounds i32, ptr [[D:%.*]], i64 [[INDEX:%.*]]
32+
; CHECK-NEXT: [[LOAD_D:%.*]] = load <vscale x 4 x i32>, ptr [[GEP_D:%.*]], align 4
33+
; CHECK-NEXT: [[MASK1:%.*]] = icmp slt <vscale x 4 x i32> [[LOAD_D:%.*]], zeroinitializer
34+
; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDEX:%.*]]
35+
; CHECK-NEXT: [[LOAD_A:%.*]] = load <vscale x 4 x i32>, ptr [[GEP_A:%.*]], align 4
36+
; CHECK-NEXT: [[MASK2:%.*]] = icmp eq <vscale x 4 x i32> [[LOAD_A:%.*]], zeroinitializer
37+
; CHECK-NEXT: [[SEL1:%.*]] = select <vscale x 4 x i1> [[MASK2:%.*]], <vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 2, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 3, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer)
38+
; CHECK-NEXT: [[SEL2:%.*]] = select <vscale x 4 x i1> [[MASK1:%.*]], <vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> poison, i32 1, i64 0), <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x i32> [[SEL1:%.*]]
39+
; CHECK-NEXT: [[ADD:%.*]] = add <vscale x 4 x i32> [[LOAD_A:%.*]], [[SEL2:%.*]]
40+
; CHECK-NEXT: store <vscale x 4 x i32> [[ADD:%.*]], ptr [[GEP_A:%.*]], align 4
41+
; CHECK-NEXT: [[INDEX_NEXT:%.*]] = add nuw i64 [[INDEX:%.*]], [[SHIFT4:%.*]]
42+
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i64 [[INDEX_NEXT:%.*]], [[N_VEC:%.*]]
43+
; CHECK-NEXT: br i1 [[LOOP_COND:%.*]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY:%.*]]
44+
45+
entry:
46+
br label %for.body
47+
48+
for.cond.cleanup: ; preds = %for.inc
49+
ret void
50+
51+
for.body: ; preds = %entry, %for.inc
52+
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ]
53+
%arrayidx = getelementptr inbounds i32, ptr %d, i64 %indvars.iv
54+
%ldr_d = load i32, ptr %arrayidx, align 4
55+
%cmp1 = icmp slt i32 %ldr_d, 0
56+
br i1 %cmp1, label %if.then, label %if.else
57+
58+
if.then: ; preds = %for.body
59+
%arrayidx3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
60+
%ldr_a = load i32, ptr %arrayidx3, align 4
61+
%add33 = add i32 %ldr_a, 1
62+
store i32 %add33, ptr %arrayidx3, align 4
63+
br label %for.inc
64+
65+
if.else: ; preds = %for.body
66+
%cmp7 = icmp eq i32 %ldr_d, 0
67+
br i1 %cmp7, label %if.then9, label %if.else15
68+
69+
if.then9: ; preds = %if.else
70+
%arrayidx11 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
71+
%ldr_a2 = load i32, ptr %arrayidx11, align 4
72+
%add1334 = add i32 %ldr_a2, 2
73+
store i32 %add1334, ptr %arrayidx11, align 4
74+
br label %for.inc
75+
76+
if.else15: ; preds = %if.else
77+
%arrayidx112 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
78+
%ldr_a3 = load i32, ptr %arrayidx112, align 4
79+
%add1935 = add i32 %ldr_a3, 3
80+
store i32 %add1935, ptr %arrayidx112, align 4
81+
br label %for.inc
82+
83+
for.inc: ; preds = %if.then, %if.else15, %if.then9
84+
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
85+
%exitcond.not = icmp eq i64 %indvars.iv.next, 20
86+
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
87+
}

0 commit comments

Comments
 (0)