Skip to content

Commit 5ae8a9b

Browse files
authored
[SimplifyCfg] Handle trunc nuw i1 condition in Equality comparison. (#153051)
proof: https://alive2.llvm.org/ce/z/WVt4-F
1 parent e44784f commit 5ae8a9b

File tree

2 files changed

+80
-7
lines changed

2 files changed

+80
-7
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -810,11 +810,15 @@ Value *SimplifyCFGOpt::isValueEqualityComparison(Instruction *TI) {
810810
if (!SI->getParent()->hasNPredecessorsOrMore(128 / SI->getNumSuccessors()))
811811
CV = SI->getCondition();
812812
} else if (BranchInst *BI = dyn_cast<BranchInst>(TI))
813-
if (BI->isConditional() && BI->getCondition()->hasOneUse())
813+
if (BI->isConditional() && BI->getCondition()->hasOneUse()) {
814814
if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition())) {
815815
if (ICI->isEquality() && getConstantInt(ICI->getOperand(1), DL))
816816
CV = ICI->getOperand(0);
817+
} else if (auto *Trunc = dyn_cast<TruncInst>(BI->getCondition())) {
818+
if (Trunc->hasNoUnsignedWrap())
819+
CV = Trunc->getOperand(0);
817820
}
821+
}
818822

819823
// Unwrap any lossless ptrtoint cast.
820824
if (CV) {
@@ -840,11 +844,20 @@ BasicBlock *SimplifyCFGOpt::getValueEqualityComparisonCases(
840844
}
841845

842846
BranchInst *BI = cast<BranchInst>(TI);
843-
ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
844-
BasicBlock *Succ = BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_NE);
845-
Cases.push_back(ValueEqualityComparisonCase(
846-
getConstantInt(ICI->getOperand(1), DL), Succ));
847-
return BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_EQ);
847+
Value *Cond = BI->getCondition();
848+
ICmpInst::Predicate Pred;
849+
ConstantInt *C;
850+
if (auto *ICI = dyn_cast<ICmpInst>(Cond)) {
851+
Pred = ICI->getPredicate();
852+
C = getConstantInt(ICI->getOperand(1), DL);
853+
} else {
854+
Pred = ICmpInst::ICMP_NE;
855+
auto *Trunc = cast<TruncInst>(Cond);
856+
C = ConstantInt::get(cast<IntegerType>(Trunc->getOperand(0)->getType()), 0);
857+
}
858+
BasicBlock *Succ = BI->getSuccessor(Pred == ICmpInst::ICMP_NE);
859+
Cases.push_back(ValueEqualityComparisonCase(C, Succ));
860+
return BI->getSuccessor(Pred == ICmpInst::ICMP_EQ);
848861
}
849862

850863
/// Given a vector of bb/value pairs, remove any entries
@@ -1106,7 +1119,10 @@ static void getBranchWeights(Instruction *TI,
11061119
// default weight to be the first entry.
11071120
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
11081121
assert(Weights.size() == 2);
1109-
ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
1122+
auto *ICI = dyn_cast<ICmpInst>(BI->getCondition());
1123+
if (!ICI)
1124+
return;
1125+
11101126
if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
11111127
std::swap(Weights.front(), Weights.back());
11121128
}

llvm/test/Transforms/SimplifyCFG/switch_create.ll

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,3 +1068,60 @@ if:
10681068
else:
10691069
ret void
10701070
}
1071+
1072+
define void @trunc_nuw_i1_condition(i32 %V) {
1073+
; CHECK-LABEL: @trunc_nuw_i1_condition(
1074+
; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
1075+
; CHECK-NEXT: i32 2, label [[T:%.*]]
1076+
; CHECK-NEXT: i32 0, label [[T]]
1077+
; CHECK-NEXT: ]
1078+
; CHECK: common.ret:
1079+
; CHECK-NEXT: ret void
1080+
; CHECK: T:
1081+
; CHECK-NEXT: call void @foo1()
1082+
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
1083+
; CHECK: F:
1084+
; CHECK-NEXT: call void @foo2()
1085+
; CHECK-NEXT: br label [[COMMON_RET]]
1086+
;
1087+
%C1 = icmp eq i32 %V, 2
1088+
br i1 %C1, label %T, label %N
1089+
N:
1090+
%C2 = trunc nuw i32 %V to i1
1091+
br i1 %C2, label %F, label %T
1092+
T:
1093+
call void @foo1( )
1094+
ret void
1095+
F:
1096+
call void @foo2( )
1097+
ret void
1098+
}
1099+
1100+
define void @neg_trunc_i1_condition(i32 %V) {
1101+
; CHECK-LABEL: @neg_trunc_i1_condition(
1102+
; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[V:%.*]], 2
1103+
; CHECK-NEXT: [[C2:%.*]] = trunc i32 [[V]] to i1
1104+
; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C1]], [[C2]]
1105+
; CHECK-NEXT: br i1 [[OR_COND]], label [[F:%.*]], label [[T:%.*]]
1106+
; CHECK: common.ret:
1107+
; CHECK-NEXT: ret void
1108+
; CHECK: T:
1109+
; CHECK-NEXT: call void @foo1()
1110+
; CHECK-NEXT: br label [[COMMON_RET:%.*]]
1111+
; CHECK: F:
1112+
; CHECK-NEXT: call void @foo2()
1113+
; CHECK-NEXT: br label [[COMMON_RET]]
1114+
;
1115+
%C1 = icmp eq i32 %V, 2
1116+
br i1 %C1, label %T, label %N
1117+
N:
1118+
%C2 = trunc i32 %V to i1
1119+
br i1 %C2, label %F, label %T
1120+
T:
1121+
call void @foo1( )
1122+
ret void
1123+
F:
1124+
call void @foo2( )
1125+
ret void
1126+
}
1127+

0 commit comments

Comments
 (0)