return Insert(BinOp, Name);
}
- Value *CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name = "") {
- assert(Cond2->getType()->isIntOrIntVectorTy(1));
- return CreateSelect(Cond1, Cond2,
- ConstantInt::getNullValue(Cond2->getType()), Name);
- }
-
- Value *CreateLogicalOr(Value *Cond1, Value *Cond2, const Twine &Name = "") {
- assert(Cond2->getType()->isIntOrIntVectorTy(1));
- return CreateSelect(Cond1, ConstantInt::getAllOnesValue(Cond2->getType()),
- Cond2, Name);
- }
-
CallInst *CreateConstrainedFPBinOp(
Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr,
const Twine &Name = "", MDNode *FPMathTag = nullptr,
/// If this basic block is ONLY a setcc and a branch, and if a predecessor
/// branches to us and one of our successors, fold the setcc into the
/// predecessor and use logical operations to pick the right destination.
-/// If PoisonSafe is true, use select i1 rather than and/or i1 to successfully
-/// block unexpected propagation of poison when merging the branches. This is
-/// set to false by default when used by LoopSimplify for performance, but this
-/// should be turned on by default.
bool FoldBranchToCommonDest(BranchInst *BI, llvm::DomTreeUpdater *DTU = nullptr,
MemorySSAUpdater *MSSAU = nullptr,
const TargetTransformInfo *TTI = nullptr,
- unsigned BonusInstThreshold = 1,
- bool PoisonSafe = false);
+ unsigned BonusInstThreshold = 1);
/// This function takes a virtual register computed by an Instruction and
/// replaces it with a slot in the stack frame, allocated via alloca.
static bool PerformBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI,
DomTreeUpdater *DTU,
- MemorySSAUpdater *MSSAU,
- bool PoisonSafe) {
+ MemorySSAUpdater *MSSAU) {
BasicBlock *BB = BI->getParent();
BasicBlock *PredBlock = PBI->getParent();
// Now that the Cond was cloned into the predecessor basic block,
// or/and the two conditions together.
- Value *NewCond = nullptr;
- Value *BICond = VMap[BI->getCondition()];
- bool UseBinOp = !PoisonSafe || impliesPoison(BICond, PBI->getCondition());
-
- if (UseBinOp)
- NewCond = Builder.CreateBinOp(Opc, PBI->getCondition(), BICond, "or.cond");
- else
- NewCond =
- Opc == Instruction::And
- ? Builder.CreateLogicalAnd(PBI->getCondition(), BICond, "or.cond")
- : Builder.CreateLogicalOr(PBI->getCondition(), BICond, "or.cond");
+ Instruction *NewCond = cast<Instruction>(Builder.CreateBinOp(
+ Opc, PBI->getCondition(), VMap[BI->getCondition()], "or.cond"));
PBI->setCondition(NewCond);
// Copy any debug value intrinsics into the end of PredBlock.
bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
MemorySSAUpdater *MSSAU,
const TargetTransformInfo *TTI,
- unsigned BonusInstThreshold,
- bool PoisonSafe) {
+ unsigned BonusInstThreshold) {
// If this block ends with an unconditional branch,
// let SpeculativelyExecuteBB() deal with it.
if (!BI->isConditional())
continue;
}
- return PerformBranchToCommonDestFolding(BI, PBI, DTU, MSSAU, PoisonSafe);
+ return PerformBranchToCommonDestFolding(BI, PBI, DTU, MSSAU);
}
return Changed;
}
// predecessor and use logical operations to update the incoming value
// for PHI nodes in common successor.
if (FoldBranchToCommonDest(BI, DTU, /*MSSAU=*/nullptr, &TTI,
- Options.BonusInstThreshold, true))
+ Options.BonusInstThreshold))
return requestResimplify();
return false;
}
// branches to us and one of our successors, fold the comparison into the
// predecessor and use logical operations to pick the right destination.
if (FoldBranchToCommonDest(BI, DTU, /*MSSAU=*/nullptr, &TTI,
- Options.BonusInstThreshold, true))
+ Options.BonusInstThreshold))
return requestResimplify();
// We have a conditional branch to two blocks that are only reachable
; CHECK-NEXT: [[V1:%.*]] = icmp ne i32 [[Z:%.*]], 1
; CHECK-NEXT: [[V0:%.*]] = icmp eq i32 [[Z]], 0
; CHECK-NEXT: [[V3_NONCHR:%.*]] = and i1 [[V0]], [[PRED:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[V1]], i1 [[V3_NONCHR]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[V1]], [[V3_NONCHR]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[BB0_NONCHR:%.*]], label [[BB1:%.*]], !prof !19
; CHECK: bb0.nonchr:
; CHECK-NEXT: call void @foo()
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[D:%.*]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[CMP]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[D:%.*]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[CMP]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[D:%.*]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[CMP]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[D:%.*]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[CMP1]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[D:%.*]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[CMP1]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; ARM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[D:%.*]], 3
; ARM-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; ARM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; ARM-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[CMP1]]
+; ARM-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP1]]
; ARM-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; ARM: cond.false:
; ARM-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; ARM-NEXT: [[CMP:%.*]] = icmp sle i32 [[D:%.*]], 3
; ARM-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; ARM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; ARM-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 true, i1 [[CMP1]]
+; ARM-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP1]]
; ARM-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; ARM: cond.false:
; ARM-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP:%.*]], true
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP_NOT]], i1 true, i1 [[CMP1]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP_NOT]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; ARM-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP:%.*]], true
; ARM-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; ARM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; ARM-NEXT: [[OR_COND:%.*]] = select i1 [[CMP_NOT]], i1 true, i1 [[CMP1]]
+; ARM-NEXT: [[OR_COND:%.*]] = or i1 [[CMP_NOT]], [[CMP1]]
; ARM-NEXT: br i1 [[OR_COND]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; ARM: cond.false:
; ARM-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP:%.*]], true
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP_NOT]], i1 [[CMP1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[CMP_NOT]], [[CMP1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; ARM-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP:%.*]], true
; ARM-NEXT: [[ADD:%.*]] = add nsw i32 [[C:%.*]], [[A:%.*]]
; ARM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B:%.*]]
-; ARM-NEXT: [[OR_COND:%.*]] = select i1 [[CMP_NOT]], i1 [[CMP1]], i1 false
+; ARM-NEXT: [[OR_COND:%.*]] = and i1 [[CMP_NOT]], [[CMP1]]
; ARM-NEXT: br i1 [[OR_COND]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
; ARM: cond.false:
; ARM-NEXT: [[TMP0:%.*]] = load i32, i32* [[INPUT:%.*]], align 4
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8* [[A:%.*]], [[B:%.*]], !annotation !0
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false, !annotation !0
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C_1]], [[C_2]], !annotation !0
; CHECK-NEXT: br i1 [[OR_COND]], label [[CONT1:%.*]], label [[TRAP:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8* [[A:%.*]], [[B:%.*]], !annotation !0
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_1]], i1 true, i1 [[C_2]], !annotation !0
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_1]], [[C_2]], !annotation !0
; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
; CHECK-NEXT: [[C_2:%.*]] = xor i1 [[C_1]], true
; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true, !annotation !0
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_2_NOT]], i1 true, i1 [[C_3]], !annotation !0
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2_NOT]], [[C_3]], !annotation !0
; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
; CHECK-NEXT: [[C_2:%.*]] = xor i1 [[C_1]], true
; CHECK-NEXT: [[C_2_NOT:%.*]] = xor i1 [[C_2]], true
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i8* [[C:%.*]], [[D:%.*]], !annotation !0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_2_NOT]], i1 true, i1 [[C_3]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C_2_NOT]], [[C_3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[TRAP:%.*]], label [[CONT1:%.*]], !annotation !0
; CHECK: trap: ; preds = %entry
; CHECK-NEXT: call void @fn1()
;CHECK: icmp eq i32
;CHECK: and i32 %c2, %k
;CHECK: icmp eq i32
-;CHECK: select i1 {{.*}}, i1 true,
+;CHECK: or i1
;CHECK: ret
define i32 @foo(i32 %k, i32 %c1, i32 %c2) {
%1 = and i32 %c1, %k
; CHECK-NEXT: pred:
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK: pred0:
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
; CHECK-NEXT: [[C3_OLD:%.*]] = icmp eq i8 [[V3:%.*]], 0
-; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[C1]], i1 true, i1 [[C3_OLD]]
+; CHECK-NEXT: [[OR_COND1:%.*]] = or i1 [[C1]], [[C3_OLD]]
; CHECK-NEXT: br i1 [[OR_COND1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: pred1:
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
; CHECK-NEXT: [[V1_ADJ:%.*]] = add i8 [[V0]], [[V1:%.*]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
; CHECK-NEXT: [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2:%.*]]
; CHECK-NEXT: [[C3_OLD:%.*]] = icmp eq i8 [[V3_ADJ_OLD]], 0
-; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[C1]], i1 true, i1 [[C3_OLD]]
+; CHECK-NEXT: [[OR_COND1:%.*]] = or i1 [[C1]], [[C3_OLD]]
; CHECK-NEXT: br i1 [[OR_COND1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: pred1:
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[V1_ADJ:%.*]] = add i8 [[V0]], [[V1:%.*]]
; CHECK-NEXT: [[V1_ADJ_ADJ:%.*]] = add i8 [[V1_ADJ]], [[V1_ADJ]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1_ADJ_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2:%.*]]
; CHECK-NEXT: [[V3_ADJ_ADJ_OLD:%.*]] = add i8 [[V3_ADJ_OLD]], [[V3_ADJ_OLD]]
; CHECK-NEXT: [[C3_OLD:%.*]] = icmp eq i8 [[V3_ADJ_ADJ_OLD]], 0
-; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[C1]], i1 true, i1 [[C3_OLD]]
+; CHECK-NEXT: [[OR_COND1:%.*]] = or i1 [[C1]], [[C3_OLD]]
; CHECK-NEXT: br i1 [[OR_COND1]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: pred1:
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[V3_ADJ_ADJ:%.*]] = add i8 [[V3_ADJ]], [[V3_ADJ]]
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3_ADJ_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
; CHECK-NEXT: [[V1_ADJ:%.*]] = add i8 [[V0]], [[V1:%.*]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
; CHECK-NEXT: [[V1_ADJ:%.*]] = add i8 [[V0]], [[V1:%.*]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
; CHECK-NEXT: [[V2_ADJ:%.*]] = add i8 [[V0]], [[V1]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C1]], [[C2]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3_ADJ]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
; CHECK-NEXT: [[V1_ADJ:%.*]] = add i8 [[V0]], [[V1:%.*]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[V0:%.*]], 0
; CHECK-NEXT: [[V1_ADJ:%.*]] = add i8 [[V0]], [[V1:%.*]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C0]], [[C1]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3:%.*]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3:%.*]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: [[V3_ADJ_OLD:%.*]] = add i8 [[V1]], [[V2]]
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V1:%.*]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3:%.*]], 0
; CHECK-NEXT: [[V2_ADJ:%.*]] = add i8 [[V4:%.*]], [[V5:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C1]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C1]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT:%.*]], label [[FINAL_RIGHT:%.*]]
; CHECK: final_left:
; CHECK-NEXT: call void @sideeffect0()
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V2:%.*]], 0
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[V3:%.*]], 0
; CHECK-NEXT: [[V3_ADJ:%.*]] = add i8 [[V4:%.*]], [[V5:%.*]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2]], i1 [[C3]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C2]], [[C3]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FINAL_LEFT]], label [[FINAL_RIGHT:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: [[C3_OLD:%.*]] = icmp eq i8 [[V3]], 0
; CHECK-NEXT: [[C2_NOT:%.*]] = xor i1 [[C2]], true
; CHECK-NEXT: [[DEC:%.*]] = add i8 [[COUNTDOWN]], -1
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[COUNTDOWN]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2_NOT]], i1 true, i1 [[CMP_NOT]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C2_NOT]], [[CMP_NOT]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END_LOOPEXIT]], label [[FOR_BODYTHREAD_PRE_SPLIT]]
; CHECK: for.bodythread-pre-split:
; CHECK-NEXT: [[DEC_MERGE]] = phi i8 [ [[DEC]], [[IF_THEN]] ], [ [[DEC_OLD]], [[FOR_INC]] ]
; CHECK-NEXT: [[C2_NOT:%.*]] = xor i1 [[C2]], true
; CHECK-NEXT: [[DEC:%.*]] = add i8 [[COUNTDOWN]], -1
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[COUNTDOWN]], 0
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C2_NOT]], i1 true, i1 [[CMP_NOT]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[C2_NOT]], [[CMP_NOT]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[IF_END_LOOPEXIT]], label [[FOR_BODYTHREAD_PRE_SPLIT]]
; CHECK: for.bodythread-pre-split:
; CHECK-NEXT: [[DEC_MERGE]] = phi i8 [ [[DEC_OLD]], [[FOR_INC]] ], [ [[DEC_MERGE]], [[FOR_BODYTHREAD_PRE_SPLIT_LOOPBACK:%.*]] ], [ [[DEC]], [[IF_THEN]] ]
; CHECK-NEXT: [[C1:%[a-z0-9]+]] = icmp eq i32 [[A1]], 0, !dbg [[DBG]]
; CHECK-NEXT: [[A2:%[a-z0-9]+]] = and i32 %c2, %k, !dbg [[DBG]]
; CHECK-NEXT: [[C2:%[a-z0-9]+]] = icmp eq i32 [[A2]], 0, !dbg [[DBG]]
-; CHECK-NEXT: [[OR:%[.a-z0-9]+]] = select i1 [[C1]], i1 true, i1 [[C2]], !dbg [[DBG]]
+; CHECK-NEXT: [[OR:%[.a-z0-9]+]] = or i1 [[C1]], [[C2]], !dbg [[DBG]]
; CHECK-NEXT: br i1 [[OR]], label {{.+}}, label {{.+}}, !dbg [[DBG]]
;
%1 = and i32 %c1, %k, !dbg !18
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_NOT:%.*]] = xor i1 [[A:%.*]], true
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[A_NOT]], i1 [[C]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[A_NOT]], [[C]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof !0
; CHECK: Y:
; CHECK-NEXT: call void @helper(i32 0)
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_NOT:%.*]] = xor i1 [[A:%.*]], true
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[A_NOT]], i1 [[C]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[A_NOT]], [[C]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof !1
; CHECK: Y:
; CHECK-NEXT: call void @helper(i32 0)
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[A:%.*]], [[C]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof !2
; CHECK: Y:
; CHECK-NEXT: call void @helper(i32 0)
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[A:%.*]], [[C]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof !1
; CHECK: Y:
; CHECK-NEXT: call void @helper(i32 0)
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 [[C]], i1 false
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[A:%.*]], [[C]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[Z:%.*]], label [[Y:%.*]], !prof !1
; CHECK: Y:
; CHECK-NEXT: call void @helper(i32 0)
; CHECK-LABEL: @test1_swap(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C:%.*]] = or i1 [[B:%.*]], false
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[C]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[A:%.*]], [[C]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[Y:%.*]], label [[Z:%.*]], !prof !5
; CHECK: Y:
; CHECK-NEXT: call void @helper(i32 0)
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[BIT_0]], 0
; CHECK-NEXT: [[V3:%.*]] = load i32, i32* @max_regno, align 4
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[I_1]], [[V3]]
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[TOBOOL]], i1 true, i1 [[CMP4]]
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TOBOOL]], [[CMP4]]
; CHECK-NEXT: br i1 [[OR_COND]], label [[FOR_EXIT:%.*]], label [[FOR_INC]], !prof !11
; CHECK: for.inc:
; CHECK-NEXT: [[SHL]] = shl i32 [[BIT_0]], 1
define void @test12() nounwind {
; CHECK-LABEL: @test12(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_OLD:%.*]] = icmp eq i32 undef, undef
-; CHECK-NEXT: br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]]
+; CHECK-NEXT: [[DOTOLD:%.*]] = icmp eq i32 undef, undef
+; CHECK-NEXT: br i1 [[DOTOLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]]
; CHECK: bb55.us.us:
; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 undef, undef
; CHECK-NEXT: [[A:%.*]] = icmp eq i32 undef, undef