diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1318,6 +1318,47 @@ 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 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(InBB->getTerminator()); + const ICmpInst *ICmp = dyn_cast(&I); + if (TerminatorBI && TerminatorBI->isConditional() && + TerminatorBI->getSuccessor(0) != TerminatorBI->getSuccessor(1) && ICmp) { + bool LHSIsTrue = TerminatorBI->getSuccessor(0) == PN->getParent(); + std::optional 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 @@ 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 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; } diff --git a/llvm/test/Transforms/InstCombine/phi.ll b/llvm/test/Transforms/InstCombine/phi.ll --- a/llvm/test/Transforms/InstCombine/phi.ll +++ b/llvm/test/Transforms/InstCombine/phi.ll @@ -1670,18 +1670,15 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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