Skip to content

Commit e88b6f1

Browse files
committed
handle add sub
1 parent 336f2ac commit e88b6f1

File tree

3 files changed

+100
-51
lines changed

3 files changed

+100
-51
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class CodeGenPrepare {
471471
bool replaceMathCmpWithIntrinsic(BinaryOperator *BO, Value *Arg0, Value *Arg1,
472472
CmpInst *Cmp, Intrinsic::ID IID);
473473
bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT);
474-
bool optimizeRem(Instruction *Rem);
474+
bool optimizeURem(Instruction *Rem);
475475
bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
476476
bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT);
477477
void verifyBFIUpdates(Function &F);
@@ -1976,26 +1976,23 @@ static bool foldFCmpToFPClassTest(CmpInst *Cmp, const TargetLowering &TLI,
19761976
}
19771977

19781978
static bool isRemOfLoopIncrementWithLoopInvariant(
1979-
Value *Rem, const LoopInfo *LI, Value *&RemAmtOut,
1980-
std::optional<bool> &AddOrSubOut, Value *&AddOrSubOffsetOut,
1981-
PHINode *&LoopIncrPNOut) {
1979+
Instruction *Rem, const LoopInfo *LI, Value *&RemAmtOut,
1980+
std::optional<bool> &AddOrSubOut, Value *&AddOrSubInstOut,
1981+
Value *&AddOrSubOffsetOut, PHINode *&LoopIncrPNOut) {
19821982
Value *Incr, *RemAmt;
1983-
if (!isa<Instruction>(Rem))
1984-
return false;
19851983
// NB: If RemAmt is a power of 2 it *should* have been transformed by now.
19861984
if (!match(Rem, m_URem(m_Value(Incr), m_Value(RemAmt))))
19871985
return false;
19881986

19891987
// Only trivially analyzable loops.
1990-
Loop *L = LI->getLoopFor(cast<Instruction>(Rem)->getParent());
1991-
if (L == nullptr || L->getLoopPreheader() == nullptr ||
1992-
L->getLoopLatch() == nullptr)
1988+
Loop *L = LI->getLoopFor(Rem->getParent());
1989+
if (!L || !L->getLoopPreheader() || !L->getLoopLatch())
19931990
return false;
19941991

19951992
std::optional<bool> AddOrSub;
19961993
Value *AddOrSubOffset;
19971994
// Find out loop increment PHI.
1998-
PHINode *PN = dyn_cast<PHINode>(Incr);
1995+
auto *PN = dyn_cast<PHINode>(Incr);
19991996
if (PN != nullptr) {
20001997
AddOrSub = std::nullopt;
20011998
AddOrSubOffset = nullptr;
@@ -2009,6 +2006,8 @@ static bool isRemOfLoopIncrementWithLoopInvariant(
20092006
else
20102007
return false;
20112008

2009+
AddOrSubInstOut = Incr;
2010+
20122011
PN = dyn_cast<PHINode>(V0);
20132012
if (PN != nullptr) {
20142013
AddOrSubOffset = V1;
@@ -2018,7 +2017,7 @@ static bool isRemOfLoopIncrementWithLoopInvariant(
20182017
}
20192018
}
20202019

2021-
if (PN == nullptr)
2020+
if (!PN)
20222021
return false;
20232022

20242023
// This isn't strictly necessary, what we really need is one increment and any
@@ -2032,7 +2031,12 @@ static bool isRemOfLoopIncrementWithLoopInvariant(
20322031

20332032
// Is the PHI a loop increment?
20342033
auto LoopIncrInfo = getIVIncrement(PN, LI);
2035-
if (!LoopIncrInfo.has_value())
2034+
if (!LoopIncrInfo)
2035+
return false;
2036+
2037+
// getIVIncrement finds the loop at PN->getParent(). This might be a different
2038+
// loop from the loop with Rem->getParent().
2039+
if (L->getHeader() != PN->getParent())
20362040
return false;
20372041

20382042
// We need remainder_amount % increment_amount to be zero. Increment of one
@@ -2045,11 +2049,6 @@ static bool isRemOfLoopIncrementWithLoopInvariant(
20452049
if (!match(LoopIncrInfo->first, m_NUWAdd(m_Value(), m_Value())))
20462050
return false;
20472051

2048-
// Need unique loop preheader and latch.
2049-
if (PN->getBasicBlockIndex(L->getLoopLatch()) < 0 ||
2050-
PN->getBasicBlockIndex(L->getLoopPreheader()) < 0)
2051-
return false;
2052-
20532052
// Set output variables.
20542053
RemAmtOut = RemAmt;
20552054
LoopIncrPNOut = PN;
@@ -2071,20 +2070,19 @@ static bool isRemOfLoopIncrementWithLoopInvariant(
20712070
// Rem = rem == RemAmtLoopInvariant ? 0 : Rem;
20722071
//
20732072
// Currently only implemented for `Start` and `IncrLoopInvariant` being zero.
2074-
static bool foldURemOfLoopIncrement(Instruction *Rem, const LoopInfo *LI,
2073+
static bool foldURemOfLoopIncrement(Instruction *Rem, const DataLayout *DL,
2074+
const LoopInfo *LI,
20752075
SmallSet<BasicBlock *, 32> &FreshBBs,
20762076
bool IsHuge) {
20772077
std::optional<bool> AddOrSub;
2078-
Value *AddOrSubOffset, *RemAmt;
2078+
Value *AddOrSubOffset, *RemAmt, *AddOrSubInst;
20792079
PHINode *LoopIncrPN;
2080-
if (!isRemOfLoopIncrementWithLoopInvariant(Rem, LI, RemAmt, AddOrSub,
2081-
AddOrSubOffset, LoopIncrPN))
2080+
if (!isRemOfLoopIncrementWithLoopInvariant(
2081+
Rem, LI, RemAmt, AddOrSub, AddOrSubInst, AddOrSubOffset, LoopIncrPN))
20822082
return false;
20832083

20842084
// Only non-constant remainder as the extra IV is probably not profitable
2085-
// in that case. Further, since remainder amount is non-constant, only handle
2086-
// case where `IncrLoopInvariant` and `Start` are 0 to entirely eliminate the
2087-
// rem (as opposed to just hoisting it outside of the loop).
2085+
// in that case.
20882086
//
20892087
// Potential TODO(1): `urem` of a const ends up as `mul` + `shift` + `add`. If
20902088
// we can rule out register pressure and ensure this `urem` is executed each
@@ -2093,12 +2091,37 @@ static bool foldURemOfLoopIncrement(Instruction *Rem, const LoopInfo *LI,
20932091
// Potential TODO(2): Should we have a check for how "nested" this remainder
20942092
// operation is? The new code runs every iteration so if the remainder is
20952093
// guarded behind unlikely conditions this might not be worth it.
2096-
if (AddOrSub.has_value() || match(RemAmt, m_ImmConstant()))
2094+
if (match(RemAmt, m_ImmConstant()))
20972095
return false;
20982096
Loop *L = LI->getLoopFor(Rem->getParent());
2099-
if (!match(LoopIncrPN->getIncomingValueForBlock(L->getLoopPreheader()),
2100-
m_Zero()))
2101-
return false;
2097+
2098+
// If we have add/sub create initial value for remainder.
2099+
// The logic here is:
2100+
// (urem (add/sub nuw Start, IncrLoopInvariant), RemAmtLoopInvariant
2101+
//
2102+
// Only proceed if the expression simplifies (otherwise we can't fully
2103+
// optimize out the urem).
2104+
Value *Start = LoopIncrPN->getIncomingValueForBlock(L->getLoopPreheader());
2105+
if (AddOrSub) {
2106+
assert(AddOrSubOffset && AddOrSubInst &&
2107+
"We found an add/sub but missing values");
2108+
// Without dom-condition/assumption cache we aren't likely to get much out
2109+
// of a context instruction.
2110+
const SimplifyQuery Q(*DL);
2111+
bool NSW = cast<OverflowingBinaryOperator>(AddOrSubInst)->hasNoSignedWrap();
2112+
if (*AddOrSub)
2113+
Start = simplifyAddInst(Start, AddOrSubOffset, /*IsNSW=*/NSW,
2114+
/*IsNUW=*/true, Q);
2115+
else
2116+
Start = simplifySubInst(Start, AddOrSubOffset, /*IsNSW=*/NSW,
2117+
/*IsNUW=*/true, Q);
2118+
if (!Start)
2119+
return false;
2120+
2121+
Start = simplifyURemInst(Start, RemAmt, Q);
2122+
if (!Start)
2123+
return false;
2124+
}
21022125

21032126
// Create new remainder with induction variable.
21042127
Type *Ty = Rem->getType();
@@ -2115,7 +2138,7 @@ static bool foldURemOfLoopIncrement(Instruction *Rem, const LoopInfo *LI,
21152138
Value *RemSel =
21162139
Builder.CreateSelect(RemCmp, Constant::getNullValue(Ty), RemAdd);
21172140

2118-
NewRem->addIncoming(Constant::getNullValue(Ty), L->getLoopPreheader());
2141+
NewRem->addIncoming(Start, L->getLoopPreheader());
21192142
NewRem->addIncoming(RemSel, L->getLoopLatch());
21202143

21212144
// Insert all touched BBs.
@@ -2125,11 +2148,13 @@ static bool foldURemOfLoopIncrement(Instruction *Rem, const LoopInfo *LI,
21252148

21262149
replaceAllUsesWith(Rem, NewRem, FreshBBs, IsHuge);
21272150
Rem->eraseFromParent();
2151+
if (AddOrSubInst && AddOrSubInst->use_empty())
2152+
cast<Instruction>(AddOrSubInst)->eraseFromParent();
21282153
return true;
21292154
}
21302155

2131-
bool CodeGenPrepare::optimizeRem(Instruction *Rem) {
2132-
if (foldURemOfLoopIncrement(Rem, LI, FreshBBs, IsHugeFunc))
2156+
bool CodeGenPrepare::optimizeURem(Instruction *Rem) {
2157+
if (foldURemOfLoopIncrement(Rem, DL, LI, FreshBBs, IsHugeFunc))
21332158
return true;
21342159
return false;
21352160
}
@@ -8520,9 +8545,8 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) {
85208545
if (optimizeCmp(Cmp, ModifiedDT))
85218546
return true;
85228547

8523-
if (match(I, m_URem(m_Value(), m_Value())) ||
8524-
match(I, m_SRem(m_Value(), m_Value())))
8525-
if (optimizeRem(I))
8548+
if (match(I, m_URem(m_Value(), m_Value())))
8549+
if (optimizeURem(I))
85268550
return true;
85278551

85288552
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {

llvm/test/CodeGen/X86/fold-loop-of-urem.ll

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -890,25 +890,31 @@ define void @simple_urem_to_sel_non_zero_start(i32 %N, i32 %rem_amt) nounwind {
890890
; CHECK-NEXT: jb .LBB16_4
891891
; CHECK-NEXT: # %bb.1: # %for.body.preheader
892892
; CHECK-NEXT: pushq %rbp
893+
; CHECK-NEXT: pushq %r15
893894
; CHECK-NEXT: pushq %r14
895+
; CHECK-NEXT: pushq %r12
894896
; CHECK-NEXT: pushq %rbx
895897
; CHECK-NEXT: movl %esi, %ebx
896898
; CHECK-NEXT: movl %edi, %ebp
897899
; CHECK-NEXT: movl $2, %r14d
900+
; CHECK-NEXT: xorl %r15d, %r15d
901+
; CHECK-NEXT: movl $2, %r12d
898902
; CHECK-NEXT: .p2align 4, 0x90
899903
; CHECK-NEXT: .LBB16_2: # %for.body
900904
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
901-
; CHECK-NEXT: movl %r14d, %eax
902-
; CHECK-NEXT: xorl %edx, %edx
903-
; CHECK-NEXT: divl %ebx
904-
; CHECK-NEXT: movl %edx, %edi
905+
; CHECK-NEXT: movl %r14d, %edi
905906
; CHECK-NEXT: callq use.i32@PLT
906907
; CHECK-NEXT: incl %r14d
907-
; CHECK-NEXT: cmpl %r14d, %ebp
908+
; CHECK-NEXT: cmpl %ebx, %r14d
909+
; CHECK-NEXT: cmovel %r15d, %r14d
910+
; CHECK-NEXT: incl %r12d
911+
; CHECK-NEXT: cmpl %r12d, %ebp
908912
; CHECK-NEXT: jne .LBB16_2
909913
; CHECK-NEXT: # %bb.3:
910914
; CHECK-NEXT: popq %rbx
915+
; CHECK-NEXT: popq %r12
911916
; CHECK-NEXT: popq %r14
917+
; CHECK-NEXT: popq %r15
912918
; CHECK-NEXT: popq %rbp
913919
; CHECK-NEXT: .LBB16_4: # %for.cond.cleanup
914920
; CHECK-NEXT: retq
@@ -1086,28 +1092,34 @@ define void @simple_urem_to_sel_non_zero_start_through_sub(i32 %N, i32 %rem_amt,
10861092
; CHECK-LABEL: simple_urem_to_sel_non_zero_start_through_sub:
10871093
; CHECK: # %bb.0: # %entry
10881094
; CHECK-NEXT: pushq %rbp
1095+
; CHECK-NEXT: pushq %r15
10891096
; CHECK-NEXT: pushq %r14
1097+
; CHECK-NEXT: pushq %r12
10901098
; CHECK-NEXT: pushq %rbx
10911099
; CHECK-NEXT: movl %edi, %ebp
10921100
; CHECK-NEXT: subl %edx, %ebp
10931101
; CHECK-NEXT: jbe .LBB20_3
10941102
; CHECK-NEXT: # %bb.1: # %for.body.preheader
10951103
; CHECK-NEXT: movl %esi, %ebx
1104+
; CHECK-NEXT: xorl %r15d, %r15d
10961105
; CHECK-NEXT: xorl %r14d, %r14d
1106+
; CHECK-NEXT: xorl %r12d, %r12d
10971107
; CHECK-NEXT: .p2align 4, 0x90
10981108
; CHECK-NEXT: .LBB20_2: # %for.body
10991109
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
1100-
; CHECK-NEXT: movl %r14d, %eax
1101-
; CHECK-NEXT: xorl %edx, %edx
1102-
; CHECK-NEXT: divl %ebx
1103-
; CHECK-NEXT: movl %edx, %edi
1110+
; CHECK-NEXT: movl %r14d, %edi
11041111
; CHECK-NEXT: callq use.i32@PLT
11051112
; CHECK-NEXT: incl %r14d
1106-
; CHECK-NEXT: cmpl %r14d, %ebp
1113+
; CHECK-NEXT: cmpl %ebx, %r14d
1114+
; CHECK-NEXT: cmovel %r15d, %r14d
1115+
; CHECK-NEXT: incl %r12d
1116+
; CHECK-NEXT: cmpl %r12d, %ebp
11071117
; CHECK-NEXT: jne .LBB20_2
11081118
; CHECK-NEXT: .LBB20_3: # %for.cond.cleanup
11091119
; CHECK-NEXT: popq %rbx
1120+
; CHECK-NEXT: popq %r12
11101121
; CHECK-NEXT: popq %r14
1122+
; CHECK-NEXT: popq %r15
11111123
; CHECK-NEXT: popq %rbp
11121124
; CHECK-NEXT: retq
11131125
entry:

llvm/test/Transforms/CodeGenPrepare/X86/fold-loop-of-urem.ll

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,12 @@ define void @simple_urem_non_zero_entry4(i32 %N, i32 %rem_amt) nounwind {
398398
; CHECK: [[FOR_COND_CLEANUP]]:
399399
; CHECK-NEXT: ret void
400400
; CHECK: [[FOR_BODY]]:
401+
; CHECK-NEXT: [[REM:%.*]] = phi i32 [ 4, %[[FOR_BODY_PREHEADER]] ], [ [[TMP3:%.*]], %[[FOR_BODY]] ]
401402
; CHECK-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 4, %[[FOR_BODY_PREHEADER]] ]
402-
; CHECK-NEXT: [[REM:%.*]] = urem i32 [[I_04]], [[REM_AMT]]
403403
; CHECK-NEXT: tail call void @use.i32(i32 [[REM]])
404+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[REM]], 1
405+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], [[REM_AMT]]
406+
; CHECK-NEXT: [[TMP3]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
404407
; CHECK-NEXT: [[INC]] = add nuw i32 [[I_04]], 1
405408
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
406409
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
@@ -469,9 +472,12 @@ define void @simple_urem_fail_no_preheader_non_canonical(i32 %N, i32 %rem_amt) n
469472
; CHECK-NEXT: [[I_04_PH:%.*]] = phi i32 [ 1, %[[FOR_BODY1]] ], [ 0, %[[ENTRY]] ]
470473
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
471474
; CHECK: [[FOR_BODY]]:
475+
; CHECK-NEXT: [[REM:%.*]] = phi i32 [ [[I_04_PH]], %[[FOR_BODY_PREHEADER]] ], [ [[TMP3:%.*]], %[[FOR_BODY]] ]
472476
; CHECK-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ [[I_04_PH]], %[[FOR_BODY_PREHEADER]] ]
473-
; CHECK-NEXT: [[REM:%.*]] = urem i32 [[I_04]], [[REM_AMT]]
474477
; CHECK-NEXT: tail call void @use.i32(i32 [[REM]])
478+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[REM]], 1
479+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], [[REM_AMT]]
480+
; CHECK-NEXT: [[TMP3]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
475481
; CHECK-NEXT: [[INC]] = add nuw i32 [[I_04]], 1
476482
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
477483
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
@@ -662,9 +668,12 @@ define void @simple_urem_to_sel_non_zero_start(i32 %N, i32 %rem_amt) nounwind {
662668
; CHECK: [[FOR_COND_CLEANUP]]:
663669
; CHECK-NEXT: ret void
664670
; CHECK: [[FOR_BODY]]:
671+
; CHECK-NEXT: [[REM:%.*]] = phi i32 [ 2, %[[FOR_BODY_PREHEADER]] ], [ [[TMP3:%.*]], %[[FOR_BODY]] ]
665672
; CHECK-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 2, %[[FOR_BODY_PREHEADER]] ]
666-
; CHECK-NEXT: [[REM:%.*]] = urem i32 [[I_04]], [[REM_AMT]]
667673
; CHECK-NEXT: tail call void @use.i32(i32 [[REM]])
674+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[REM]], 1
675+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], [[REM_AMT]]
676+
; CHECK-NEXT: [[TMP3]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
668677
; CHECK-NEXT: [[INC]] = add nuw i32 [[I_04]], 1
669678
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
670679
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
@@ -697,10 +706,12 @@ define void @simple_urem_to_sel_non_zero_start_through_add(i32 %N, i32 %rem_amt_
697706
; CHECK: [[FOR_COND_CLEANUP]]:
698707
; CHECK-NEXT: ret void
699708
; CHECK: [[FOR_BODY]]:
709+
; CHECK-NEXT: [[REM:%.*]] = phi i32 [ 7, %[[FOR_BODY_PREHEADER]] ], [ [[TMP3:%.*]], %[[FOR_BODY]] ]
700710
; CHECK-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 2, %[[FOR_BODY_PREHEADER]] ]
701-
; CHECK-NEXT: [[I_WITH_OFF:%.*]] = add nuw i32 [[I_04]], 5
702-
; CHECK-NEXT: [[REM:%.*]] = urem i32 [[I_WITH_OFF]], [[REM_AMT]]
703711
; CHECK-NEXT: tail call void @use.i32(i32 [[REM]])
712+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[REM]], 1
713+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], [[REM_AMT]]
714+
; CHECK-NEXT: [[TMP3]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
704715
; CHECK-NEXT: [[INC]] = add nuw i32 [[I_04]], 1
705716
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
706717
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
@@ -808,10 +819,12 @@ define void @simple_urem_to_sel_non_zero_start_through_sub(i32 %N, i32 %rem_amt,
808819
; CHECK: [[FOR_COND_CLEANUP]]:
809820
; CHECK-NEXT: ret void
810821
; CHECK: [[FOR_BODY]]:
822+
; CHECK-NEXT: [[REM:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[TMP3:%.*]], %[[FOR_BODY]] ]
811823
; CHECK-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ [[START]], %[[FOR_BODY_PREHEADER]] ]
812-
; CHECK-NEXT: [[I_WITH_OFF:%.*]] = sub nuw i32 [[I_04]], [[START]]
813-
; CHECK-NEXT: [[REM:%.*]] = urem i32 [[I_WITH_OFF]], [[REM_AMT]]
814824
; CHECK-NEXT: tail call void @use.i32(i32 [[REM]])
825+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[REM]], 1
826+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], [[REM_AMT]]
827+
; CHECK-NEXT: [[TMP3]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
815828
; CHECK-NEXT: [[INC]] = add nuw i32 [[I_04]], 1
816829
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
817830
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]

0 commit comments

Comments
 (0)