Skip to content

Commit e11f93e

Browse files
authored
[SimplifyCFG] Support not in chain of comparisons. (#156497)
Proof: https://alive2.llvm.org/ce/z/cpXuCb
1 parent 879f40a commit e11f93e

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,9 @@ struct ConstantComparesGatherer {
612612
/// If CompValue is already set, the function is expected to fail if a match
613613
/// is found but the value compared to is different.
614614
bool matchInstruction(Instruction *I, bool isEQ) {
615+
if (match(I, m_Not(m_Instruction(I))))
616+
isEQ = !isEQ;
617+
615618
Value *Val;
616619
if (match(I, m_NUWTrunc(m_Value(Val)))) {
617620
// If we already have a value for the switch, it has to match!

llvm/test/Transforms/SimplifyCFG/switch_create.ll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,3 +1265,51 @@ if.then:
12651265
if.end:
12661266
ret void
12671267
}
1268+
1269+
define void @and_chain_trunc_nuw_not_i1_condition(i8 %x) {
1270+
; CHECK-LABEL: @and_chain_trunc_nuw_not_i1_condition(
1271+
; CHECK-NEXT: [[X_OFF:%.*]] = add i8 [[X:%.*]], -1
1272+
; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[X_OFF]], 4
1273+
; CHECK-NEXT: br i1 [[SWITCH]], label [[COMMON_RET:%.*]], label [[IF_THEN:%.*]]
1274+
; CHECK: common.ret:
1275+
; CHECK-NEXT: ret void
1276+
; CHECK: if.then:
1277+
; CHECK-NEXT: tail call void @foo1()
1278+
; CHECK-NEXT: br label [[COMMON_RET]]
1279+
;
1280+
%add = add nsw i8 %x, -2
1281+
%icmp = icmp ugt i8 %add, 2
1282+
%trunc = trunc nuw i8 %x to i1
1283+
%not = xor i1 %trunc, true
1284+
%and = select i1 %icmp, i1 %not, i1 false
1285+
br i1 %and, label %if.then, label %if.end
1286+
if.then:
1287+
tail call void @foo1()
1288+
ret void
1289+
if.end:
1290+
ret void
1291+
}
1292+
1293+
define void @or_chain_trunc_nuw_not_i1_condition(i8 %x) {
1294+
; CHECK-LABEL: @or_chain_trunc_nuw_not_i1_condition(
1295+
; CHECK-NEXT: switch i8 [[X:%.*]], label [[COMMON_RET:%.*]] [
1296+
; CHECK-NEXT: i8 2, label [[IF_THEN:%.*]]
1297+
; CHECK-NEXT: i8 0, label [[IF_THEN]]
1298+
; CHECK-NEXT: ]
1299+
; CHECK: common.ret:
1300+
; CHECK-NEXT: ret void
1301+
; CHECK: if.then:
1302+
; CHECK-NEXT: tail call void @foo1()
1303+
; CHECK-NEXT: br label [[COMMON_RET]]
1304+
;
1305+
%icmp = icmp eq i8 %x, 2
1306+
%trunc = trunc nuw i8 %x to i1
1307+
%not = xor i1 %trunc, true
1308+
%or = select i1 %icmp, i1 true, i1 %not
1309+
br i1 %or, label %if.then, label %if.end
1310+
if.then:
1311+
tail call void @foo1()
1312+
ret void
1313+
if.end:
1314+
ret void
1315+
}

0 commit comments

Comments
 (0)