[InstCombine] Improve foldOpIntoPhi() to use isImpliedCondition

Improve foldOpIntoPhi() for icmp operator to check if incoming PHI value can be replaced with constant based on implied condition.

Depends on D156619.

Differential Revision: https://reviews.llvm.org/D156620
This commit is contained in:
Maksim Kita 2023-08-01 12:09:05 +03:00
parent 2c4e1df9a1
commit 991855ea8a
2 changed files with 122 additions and 138 deletions

View File

@ -1318,6 +1318,47 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr, SI);
}
static Value *simplifyInstructionWithPHI(Instruction &I, PHINode *PN,
Value *InValue, BasicBlock *InBB,
const DataLayout &DL,
const SimplifyQuery SQ) {
// NB: It is a precondition of this transform that the operands be
// phi translatable! This is usually trivially satisfied by limiting it
// to constant ops, and for selects we do a more sophisticated check.
SmallVector<Value *> Ops;
for (Value *Op : I.operands()) {
if (Op == PN)
Ops.push_back(InValue);
else
Ops.push_back(Op->DoPHITranslation(PN->getParent(), InBB));
}
// Don't consider the simplification successful if we get back a constant
// expression. That's just an instruction in hiding.
// Also reject the case where we simplify back to the phi node. We wouldn't
// be able to remove it in that case.
Value *NewVal = simplifyInstructionWithOperands(
&I, Ops, SQ.getWithInstruction(InBB->getTerminator()));
if (NewVal && NewVal != PN && !match(NewVal, m_ConstantExpr()))
return NewVal;
// Check if incoming PHI value can be replaced with constant
// based on implied condition.
BranchInst *TerminatorBI = dyn_cast<BranchInst>(InBB->getTerminator());
const ICmpInst *ICmp = dyn_cast<ICmpInst>(&I);
if (TerminatorBI && TerminatorBI->isConditional() &&
TerminatorBI->getSuccessor(0) != TerminatorBI->getSuccessor(1) && ICmp) {
bool LHSIsTrue = TerminatorBI->getSuccessor(0) == PN->getParent();
std::optional<bool> ImpliedCond =
isImpliedCondition(TerminatorBI->getCondition(), ICmp->getPredicate(),
Ops[0], Ops[1], DL, LHSIsTrue);
if (ImpliedCond)
return ConstantInt::getBool(I.getType(), ImpliedCond.value());
}
return nullptr;
}
Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
unsigned NumPHIValues = PN->getNumIncomingValues();
if (NumPHIValues == 0)
@ -1346,24 +1387,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
Value *InVal = PN->getIncomingValue(i);
BasicBlock *InBB = PN->getIncomingBlock(i);
// NB: It is a precondition of this transform that the operands be
// phi translatable! This is usually trivially satisfied by limiting it
// to constant ops, and for selects we do a more sophisticated check.
SmallVector<Value *> Ops;
for (Value *Op : I.operands()) {
if (Op == PN)
Ops.push_back(InVal);
else
Ops.push_back(Op->DoPHITranslation(PN->getParent(), InBB));
}
// Don't consider the simplification successful if we get back a constant
// expression. That's just an instruction in hiding.
// Also reject the case where we simplify back to the phi node. We wouldn't
// be able to remove it in that case.
Value *NewVal = simplifyInstructionWithOperands(
&I, Ops, SQ.getWithInstruction(InBB->getTerminator()));
if (NewVal && NewVal != PN && !match(NewVal, m_ConstantExpr())) {
if (auto *NewVal = simplifyInstructionWithPHI(I, PN, InVal, InBB, DL, SQ)) {
NewPhiValues.push_back(NewVal);
continue;
}

View File

@ -1670,18 +1670,15 @@ if.end:
define i1 @cmp_eq_phi_node_can_fold_1(ptr %C) {
; CHECK-LABEL: @cmp_eq_phi_node_can_fold_1(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1705,25 +1702,20 @@ join:
define i1 @cmp_eq_phi_node_can_fold_2(ptr %C) {
; CHECK-LABEL: @cmp_eq_phi_node_can_fold_2(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: br i1 [[TMP9]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
; CHECK-NEXT: br i1 [[TMP5]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
; CHECK: sub_is_zero1:
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i8 [[TMP7]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP13]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ false, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1755,18 +1747,15 @@ join:
define i1 @cmp_eq_phi_node_can_fold_3(ptr %C) {
; CHECK-LABEL: @cmp_eq_phi_node_can_fold_3(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1791,25 +1780,20 @@ join:
define i1 @cmp_eq_phi_node_can_fold_4(ptr %C) {
; CHECK-LABEL: @cmp_eq_phi_node_can_fold_4(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: br i1 [[TMP9]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
; CHECK: sub_is_zero1:
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i8 [[TMP7]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP13]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ true, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1841,18 +1825,15 @@ join:
define i1 @cmp_ne_phi_node_can_fold_1(ptr %C) {
; CHECK-LABEL: @cmp_ne_phi_node_can_fold_1(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP8]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1876,25 +1857,20 @@ join:
define i1 @cmp_ne_phi_node_can_fold_2(ptr %C) {
; CHECK-LABEL: @cmp_ne_phi_node_can_fold_2(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[SUB_IS_ZERO:%.*]], label [[JOIN:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: br i1 [[TMP9]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
; CHECK-NEXT: br i1 [[TMP5]], label [[SUB_IS_ZERO1:%.*]], label [[JOIN]]
; CHECK: sub_is_zero1:
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP7]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP13]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, [[TMP0:%.*]] ], [ true, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1926,18 +1902,15 @@ join:
define i1 @cmp_ne_phi_node_can_fold_3(ptr %C) {
; CHECK-LABEL: @cmp_ne_phi_node_can_fold_3(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP8]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -1961,25 +1934,20 @@ join:
define i1 @cmp_ne_phi_node_can_fold_4(ptr %C) {
; CHECK-LABEL: @cmp_ne_phi_node_can_fold_4(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: br i1 [[TMP9]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
; CHECK: sub_is_zero1:
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP7]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP13]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ false, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -2011,18 +1979,15 @@ join:
define i1 @cmp_sgt_phi_node_can_fold_1(ptr %C) {
; CHECK-LABEL: @cmp_sgt_phi_node_can_fold_1(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP8]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP5]], [[SUB_IS_ZERO]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1
@ -2046,25 +2011,20 @@ join:
define i1 @cmp_sgt_phi_node_can_fold_2(ptr %C) {
; CHECK-LABEL: @cmp_sgt_phi_node_can_fold_2(
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[TMP2]], -48
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TMP4]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 48
; CHECK-NEXT: br i1 [[TMP2]], label [[JOIN:%.*]], label [[SUB_IS_ZERO:%.*]]
; CHECK: sub_is_zero:
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], -49
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
; CHECK-NEXT: br i1 [[TMP9]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP4]], 49
; CHECK-NEXT: br i1 [[TMP5]], label [[JOIN]], label [[SUB_IS_ZERO1:%.*]]
; CHECK: sub_is_zero1:
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
; CHECK-NEXT: [[TMP7:%.*]] = load i8, ptr [[TMP6]], align 1
; CHECK-NEXT: [[TMP8:%.*]] = icmp ne i8 [[TMP7]], 0
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[SUB_IS_ZERO]] ], [ [[TMP12]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP13]], 0
; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ false, [[SUB_IS_ZERO]] ], [ [[TMP8]], [[SUB_IS_ZERO1]] ]
; CHECK-NEXT: ret i1 [[CMP]]
;
%1 = load i8, ptr %C, align 1