Skip to content

Commit ed742f8

Browse files
authored
[SimplifyCFG] Handle that first matched eq cond in if chain can be Extra condition. (#154007)
Proof: https://alive2.llvm.org/ce/z/TozSD6
1 parent 4676242 commit ed742f8

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,20 @@ struct ConstantComparesGatherer {
568568
/// If the elements in Vals matches the comparisons
569569
bool IsEq = false;
570570

571+
// Used to check if the first matched CompValue shall be the Extra check.
572+
bool IgnoreFirstMatch = false;
573+
bool MultipleMatches = false;
574+
571575
/// Construct and compute the result for the comparison instruction Cond
572576
ConstantComparesGatherer(Instruction *Cond, const DataLayout &DL) : DL(DL) {
573577
gather(Cond);
578+
if (CompValue || !MultipleMatches)
579+
return;
580+
Extra = nullptr;
581+
Vals.clear();
582+
UsedICmps = 0;
583+
IgnoreFirstMatch = true;
584+
gather(Cond);
574585
}
575586

576587
ConstantComparesGatherer(const ConstantComparesGatherer &) = delete;
@@ -581,10 +592,16 @@ struct ConstantComparesGatherer {
581592
/// Try to set the current value used for the comparison, it succeeds only if
582593
/// it wasn't set before or if the new value is the same as the old one
583594
bool setValueOnce(Value *NewVal) {
584-
if (CompValue && CompValue != NewVal)
595+
if (IgnoreFirstMatch) {
596+
IgnoreFirstMatch = false;
585597
return false;
598+
}
599+
if (CompValue && CompValue != NewVal) {
600+
MultipleMatches = true;
601+
return false;
602+
}
586603
CompValue = NewVal;
587-
return (CompValue != nullptr);
604+
return true;
588605
}
589606

590607
/// Try to match Instruction "I" as a comparison against a constant and

llvm/test/Transforms/SimplifyCFG/switch_create.ll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,3 +1125,70 @@ F:
11251125
ret void
11261126
}
11271127

1128+
define void @extra_cond_is_eq_cmp(i8 %c, i32 %x) {
1129+
; CHECK-LABEL: @extra_cond_is_eq_cmp(
1130+
; CHECK-NEXT: entry:
1131+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 32
1132+
; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 [[CMP]]
1133+
; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
1134+
; CHECK: switch.early.test:
1135+
; CHECK-NEXT: switch i8 [[C:%.*]], label [[COMMON_RET:%.*]] [
1136+
; CHECK-NEXT: i8 99, label [[IF_THEN]]
1137+
; CHECK-NEXT: i8 97, label [[IF_THEN]]
1138+
; CHECK-NEXT: ]
1139+
; CHECK: common.ret:
1140+
; CHECK-NEXT: ret void
1141+
; CHECK: if.then:
1142+
; CHECK-NEXT: tail call void @foo1()
1143+
; CHECK-NEXT: br label [[COMMON_RET]]
1144+
;
1145+
entry:
1146+
%cmp = icmp eq i32 %x, 32
1147+
%cmp4 = icmp eq i8 %c, 97
1148+
%or.cond = or i1 %cmp, %cmp4
1149+
%cmp9 = icmp eq i8 %c, 99
1150+
%or.cond11 = or i1 %or.cond, %cmp9
1151+
br i1 %or.cond11, label %if.then, label %if.end
1152+
1153+
if.then:
1154+
tail call void @foo1()
1155+
ret void
1156+
1157+
if.end:
1158+
ret void
1159+
1160+
}
1161+
1162+
define void @extra_cond_is_eq_cmp_c(i8 %c, i32 %x) {
1163+
; CHECK-LABEL: @extra_cond_is_eq_cmp_c(
1164+
; CHECK-NEXT: entry:
1165+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 32
1166+
; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 [[CMP]]
1167+
; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
1168+
; CHECK: switch.early.test:
1169+
; CHECK-NEXT: switch i8 [[C:%.*]], label [[COMMON_RET:%.*]] [
1170+
; CHECK-NEXT: i8 99, label [[IF_THEN]]
1171+
; CHECK-NEXT: i8 97, label [[IF_THEN]]
1172+
; CHECK-NEXT: ]
1173+
; CHECK: common.ret:
1174+
; CHECK-NEXT: ret void
1175+
; CHECK: if.then:
1176+
; CHECK-NEXT: tail call void @foo1()
1177+
; CHECK-NEXT: br label [[COMMON_RET]]
1178+
;
1179+
entry:
1180+
%cmp = icmp eq i32 %x, 32
1181+
%cmp4 = icmp eq i8 %c, 97
1182+
%or.cond = or i1 %cmp4, %cmp
1183+
%cmp9 = icmp eq i8 %c, 99
1184+
%or.cond11 = or i1 %or.cond, %cmp9
1185+
br i1 %or.cond11, label %if.then, label %if.end
1186+
1187+
if.then:
1188+
tail call void @foo1()
1189+
ret void
1190+
1191+
if.end:
1192+
ret void
1193+
1194+
}

0 commit comments

Comments
 (0)