Skip to content

Commit a5eebc8

Browse files
committed
[SelectOpt] Support BinOps with SExt operands. (llvm#115879)
Building on top of llvm#115489 extend support for binops with SExt operand. PR: llvm#115879 (cherry picked from commit c1f5937)
1 parent 83c7979 commit a5eebc8

File tree

2 files changed

+112
-58
lines changed

2 files changed

+112
-58
lines changed

llvm/lib/CodeGen/SelectOptimize.cpp

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,14 @@ static Value *getTrueOrFalseValue(
497497

498498
auto *CBO = BO->clone();
499499
auto CondIdx = SI.getConditionOpIndex();
500-
CBO->setOperand(CondIdx, ConstantInt::get(CBO->getType(), 1));
500+
auto *AuxI = cast<Instruction>(CBO->getOperand(CondIdx));
501+
if (isa<ZExtInst>(AuxI)) {
502+
CBO->setOperand(CondIdx, ConstantInt::get(CBO->getType(), 1));
503+
} else {
504+
assert(isa<SExtInst>(AuxI) &&
505+
"Unexpected opcode");
506+
CBO->setOperand(CondIdx, ConstantInt::get(CBO->getType(), -1));
507+
}
501508

502509
unsigned OtherIdx = 1 - CondIdx;
503510
if (auto *IV = dyn_cast<Instruction>(CBO->getOperand(OtherIdx))) {
@@ -755,6 +762,7 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
755762
// Auxiliary instruction are instructions that depends on a condition and have
756763
// zero or some constant value on True/False branch, such as:
757764
// * ZExt(1bit)
765+
// * SExt(1bit)
758766
// * Not(1bit)
759767
struct SelectLikeInfo {
760768
Value *Cond;
@@ -770,7 +778,7 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
770778
// inserted position.
771779
auto ProcessSelectInfo = [&SelectInfo](Instruction *I) {
772780
Value *Cond;
773-
if (match(I, m_OneUse(m_ZExt(m_Value(Cond)))) &&
781+
if (match(I, m_OneUse(m_ZExtOrSExt(m_Value(Cond)))) &&
774782
Cond->getType()->isIntegerTy(1)) {
775783
bool Inverted = match(Cond, m_Not(m_Value(Cond)));
776784
return SelectInfo.insert({I, {Cond, true, Inverted, 0}}).first;
@@ -788,32 +796,30 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
788796

789797
// An Or(zext(i1 X), Y) can also be treated like a select, with condition X
790798
// and values Y|1 and Y.
791-
if (auto *BO = dyn_cast<BinaryOperator>(I)) {
792-
switch (I->getOpcode()) {
793-
case Instruction::Add:
794-
case Instruction::Sub: {
795-
Value *X;
796-
if (!((PatternMatch::match(I->getOperand(0),
797-
m_OneUse(m_ZExt(m_Value(X)))) ||
798-
PatternMatch::match(I->getOperand(1),
799-
m_OneUse(m_ZExt(m_Value(X))))) &&
800-
X->getType()->isIntegerTy(1)))
801-
return SelectInfo.end();
802-
break;
803-
}
804-
case Instruction::Or:
805-
if (BO->getType()->isIntegerTy(1) || BO->getOpcode() != Instruction::Or)
806-
return SelectInfo.end();
807-
break;
808-
}
799+
// `Aux` can be either `ZExt(1bit)` or `SExt(1bit)`, ValBitSize
800+
// - 1` `BinOp` can be Add, Sub, Or
801+
Value *X;
802+
auto MatchZExtOrSExtPattern =
803+
m_c_BinOp(m_Value(), m_OneUse(m_ZExtOrSExt(m_Value(X))));
804+
805+
// This check is unnecessary, but it prevents costly access to the
806+
// SelectInfo map.
807+
if ((match(I, MatchZExtOrSExtPattern) && X->getType()->isIntegerTy(1))) {
808+
if (I->getOpcode() != Instruction::Add &&
809+
I->getOpcode() != Instruction::Sub &&
810+
I->getOpcode() != Instruction::Or)
811+
return SelectInfo.end();
812+
813+
if (I->getOpcode() == Instruction::Or && I->getType()->isIntegerTy(1))
814+
return SelectInfo.end();
809815

810816
// Iterate through operands and find dependant on recognised sign
811817
// extending auxiliary select-like instructions. The operand index does
812818
// not matter for Add and Or. However, for Sub, we can only safely
813819
// transform when the operand is second.
814-
unsigned Idx = BO->getOpcode() == Instruction::Sub ? 1 : 0;
820+
unsigned Idx = I->getOpcode() == Instruction::Sub ? 1 : 0;
815821
for (; Idx < 2; Idx++) {
816-
auto *Op = BO->getOperand(Idx);
822+
auto *Op = I->getOperand(Idx);
817823
auto It = SelectInfo.find(Op);
818824
if (It != SelectInfo.end() && It->second.IsAuxiliary) {
819825
Cond = It->second.Cond;

llvm/test/CodeGen/AArch64/selectopt-cast.ll

Lines changed: 84 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,22 @@ define void @test_add_sext(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.star
168168
; CHECK-NEXT: entry:
169169
; CHECK-NEXT: br label [[LOOP:%.*]]
170170
; CHECK: loop:
171-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
172-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
173-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
171+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ]
172+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ]
173+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ]
174174
; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
175175
; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8
176176
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
177177
; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8
178178
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]
179179
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[CMP3]] to i64
180-
; CHECK-NEXT: [[J_NEXT]] = add nsw i64 [[J]], [[DEC]]
180+
; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
181+
; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]]
182+
; CHECK: select.true.sink:
183+
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], -1
184+
; CHECK-NEXT: br label [[SELECT_END]]
185+
; CHECK: select.end:
186+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ]
181187
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
182188
; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8
183189
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -215,17 +221,23 @@ define void @test_add_sext_not(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.
215221
; CHECK-NEXT: entry:
216222
; CHECK-NEXT: br label [[LOOP:%.*]]
217223
; CHECK: loop:
218-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
219-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
220-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
224+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ]
225+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ]
226+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ]
221227
; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
222228
; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8
223229
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
224230
; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8
225231
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]
226232
; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true
227233
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64
228-
; CHECK-NEXT: [[J_NEXT]] = add nsw i64 [[J]], [[DEC]]
234+
; CHECK-NEXT: [[NOT_CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
235+
; CHECK-NEXT: br i1 [[NOT_CMP3_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]]
236+
; CHECK: select.false.sink:
237+
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], -1
238+
; CHECK-NEXT: br label [[SELECT_END]]
239+
; CHECK: select.end:
240+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE]] ]
229241
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
230242
; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8
231243
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -264,18 +276,24 @@ define void @test_add_sext_not_and_regular_select(ptr %dst, ptr %src, i64 %j.sta
264276
; CHECK-NEXT: entry:
265277
; CHECK-NEXT: br label [[LOOP:%.*]]
266278
; CHECK: loop:
267-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
268-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
269-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
279+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ]
280+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ]
281+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ]
270282
; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
271283
; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8
272284
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
273285
; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8
274286
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]
275287
; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true
276288
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64
277-
; CHECK-NEXT: [[J_NEXT]] = add nsw i64 [[J]], [[DEC]]
278-
; CHECK-NEXT: [[SINK:%.*]] = select i1 [[CMP3]], ptr [[L_I]], ptr [[L_J]]
289+
; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
290+
; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE_SINK:%.*]]
291+
; CHECK: select.false.sink:
292+
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[J]], -1
293+
; CHECK-NEXT: br label [[SELECT_END1]]
294+
; CHECK: select.end:
295+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE_SINK]] ]
296+
; CHECK-NEXT: [[SINK:%.*]] = phi ptr [ [[L_I]], [[LOOP]] ], [ [[L_J]], [[SELECT_FALSE_SINK]] ]
279297
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
280298
; CHECK-NEXT: store ptr [[SINK]], ptr [[GEP_DST]], align 8
281299
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -315,9 +333,9 @@ define void @test_add_sext_not_and_regular_select2(ptr %dst, ptr %src, i64 %j.st
315333
; CHECK-NEXT: entry:
316334
; CHECK-NEXT: br label [[LOOP:%.*]]
317335
; CHECK: loop:
318-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
319-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
320-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
336+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ]
337+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ]
338+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ]
321339
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
322340
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX1]], align 8
323341
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
@@ -327,10 +345,16 @@ define void @test_add_sext_not_and_regular_select2(ptr %dst, ptr %src, i64 %j.st
327345
; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[P]]
328346
; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX1_I]], align 8
329347
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i64 [[TMP2]], [[TMP3]]
330-
; CHECK-NEXT: [[DOTSINK:%.*]] = select i1 [[CMP3]], ptr [[TMP0]], ptr [[TMP1]]
348+
; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
349+
; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE:%.*]]
350+
; CHECK: select.false.sink:
351+
; CHECK-NEXT: [[TMP5:%.*]] = add nsw i64 [[J]], -1
352+
; CHECK-NEXT: br label [[SELECT_END1]]
353+
; CHECK: select.end:
354+
; CHECK-NEXT: [[DOTSINK:%.*]] = phi ptr [ [[TMP0]], [[LOOP]] ], [ [[TMP1]], [[SELECT_FALSE]] ]
355+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP5]], [[SELECT_FALSE]] ]
331356
; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true
332357
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64
333-
; CHECK-NEXT: [[J_NEXT]] = add nsw i64 [[J]], [[DEC]]
334358
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
335359
; CHECK-NEXT: store ptr [[DOTSINK]], ptr [[TMP4]], align 8
336360
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -529,16 +553,22 @@ define void @test_sub_sext(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.star
529553
; CHECK-NEXT: entry:
530554
; CHECK-NEXT: br label [[LOOP:%.*]]
531555
; CHECK: loop:
532-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
533-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
534-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
556+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ]
557+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ]
558+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ]
535559
; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
536560
; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8
537561
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
538562
; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8
539563
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]
540564
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[CMP3]] to i64
541-
; CHECK-NEXT: [[J_NEXT]] = sub nsw i64 [[J]], [[DEC]]
565+
; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
566+
; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END]]
567+
; CHECK: select.true.sink:
568+
; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], -1
569+
; CHECK-NEXT: br label [[SELECT_END]]
570+
; CHECK: select.end:
571+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[TMP0]], [[SELECT_TRUE_SINK]] ], [ [[J]], [[LOOP]] ]
542572
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
543573
; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8
544574
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -576,17 +606,23 @@ define void @test_sub_sext_not(ptr %dst, ptr %src, i64 %j.start, i64 %p, i64 %i.
576606
; CHECK-NEXT: entry:
577607
; CHECK-NEXT: br label [[LOOP:%.*]]
578608
; CHECK: loop:
579-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
580-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
581-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
609+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END:%.*]] ]
610+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END]] ]
611+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END]] ]
582612
; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
583613
; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8
584614
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
585615
; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8
586616
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]
587617
; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true
588618
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64
589-
; CHECK-NEXT: [[J_NEXT]] = sub nsw i64 [[J]], [[DEC]]
619+
; CHECK-NEXT: [[NOT_CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
620+
; CHECK-NEXT: br i1 [[NOT_CMP3_FROZEN]], label [[SELECT_END]], label [[SELECT_FALSE:%.*]]
621+
; CHECK: select.false.sink:
622+
; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], -1
623+
; CHECK-NEXT: br label [[SELECT_END]]
624+
; CHECK: select.end:
625+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE]] ]
590626
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
591627
; CHECK-NEXT: store i64 [[J_NEXT]], ptr [[GEP_DST]], align 8
592628
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -625,18 +661,24 @@ define void @test_sub_sext_not_and_regular_select(ptr %dst, ptr %src, i64 %j.sta
625661
; CHECK-NEXT: entry:
626662
; CHECK-NEXT: br label [[LOOP:%.*]]
627663
; CHECK: loop:
628-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
629-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
630-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
664+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ]
665+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ]
666+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ]
631667
; CHECK-NEXT: [[GEP_I:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
632668
; CHECK-NEXT: [[L_I:%.*]] = load ptr, ptr [[GEP_I]], align 8
633669
; CHECK-NEXT: [[GEP_J:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
634670
; CHECK-NEXT: [[L_J:%.*]] = load ptr, ptr [[GEP_J]], align 8
635671
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult ptr [[L_I]], [[L_J]]
636672
; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true
637673
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64
638-
; CHECK-NEXT: [[J_NEXT]] = sub nsw i64 [[J]], [[DEC]]
639-
; CHECK-NEXT: [[SINK:%.*]] = select i1 [[CMP3]], ptr [[L_I]], ptr [[L_J]]
674+
; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
675+
; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE_SINK:%.*]]
676+
; CHECK: select.false.sink:
677+
; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[J]], -1
678+
; CHECK-NEXT: br label [[SELECT_END1]]
679+
; CHECK: select.end:
680+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP0]], [[SELECT_FALSE_SINK]] ]
681+
; CHECK-NEXT: [[SINK:%.*]] = phi ptr [ [[L_I]], [[LOOP]] ], [ [[L_J]], [[SELECT_FALSE_SINK]] ]
640682
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
641683
; CHECK-NEXT: store ptr [[SINK]], ptr [[GEP_DST]], align 8
642684
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
@@ -676,9 +718,9 @@ define void @test_sub_sext_not_and_regular_select2(ptr %dst, ptr %src, i64 %j.st
676718
; CHECK-NEXT: entry:
677719
; CHECK-NEXT: br label [[LOOP:%.*]]
678720
; CHECK: loop:
679-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
680-
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[LOOP]] ]
681-
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[LOOP]] ]
721+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[SELECT_END1:%.*]] ]
722+
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[HIGH:%.*]], [[ENTRY]] ], [ [[J_NEXT:%.*]], [[SELECT_END1]] ]
723+
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_START:%.*]], [[ENTRY]] ], [ [[J_NEXT]], [[SELECT_END1]] ]
682724
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds ptr, ptr [[SRC:%.*]], i64 [[I]]
683725
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX1]], align 8
684726
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[J]]
@@ -688,10 +730,16 @@ define void @test_sub_sext_not_and_regular_select2(ptr %dst, ptr %src, i64 %j.st
688730
; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i64 [[P]]
689731
; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[ARRAYIDX1_I]], align 8
690732
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i64 [[TMP2]], [[TMP3]]
691-
; CHECK-NEXT: [[DOTSINK:%.*]] = select i1 [[CMP3]], ptr [[TMP0]], ptr [[TMP1]]
733+
; CHECK-NEXT: [[CMP3_FROZEN:%.*]] = freeze i1 [[CMP3]]
734+
; CHECK-NEXT: br i1 [[CMP3_FROZEN]], label [[SELECT_END1]], label [[SELECT_FALSE:%.*]]
735+
; CHECK: select.false.sink:
736+
; CHECK-NEXT: [[TMP5:%.*]] = sub nsw i64 [[J]], -1
737+
; CHECK-NEXT: br label [[SELECT_END1]]
738+
; CHECK: select.end:
739+
; CHECK-NEXT: [[DOTSINK:%.*]] = phi ptr [ [[TMP0]], [[LOOP]] ], [ [[TMP1]], [[SELECT_FALSE]] ]
740+
; CHECK-NEXT: [[J_NEXT]] = phi i64 [ [[J]], [[LOOP]] ], [ [[TMP5]], [[SELECT_FALSE]] ]
692741
; CHECK-NEXT: [[NOT_CMP3:%.*]] = xor i1 [[CMP3]], true
693742
; CHECK-NEXT: [[DEC:%.*]] = sext i1 [[NOT_CMP3]] to i64
694-
; CHECK-NEXT: [[J_NEXT]] = sub nsw i64 [[J]], [[DEC]]
695743
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 [[IV]]
696744
; CHECK-NEXT: store ptr [[DOTSINK]], ptr [[TMP4]], align 8
697745
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1

0 commit comments

Comments
 (0)