[llvm] [SimplifyCFG] Handle that first matched eq cond in if chain can be Extra condition. (PR #154007)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 22 13:22:23 PDT 2025
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/154007
>From d18a99959644d36a9f65a3c250aa5ddb1dd0b3d8 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sun, 17 Aug 2025 10:23:25 +0200
Subject: [PATCH 1/3] [SimplifyCFG] Add test with multiple eq cond in if chain
(NFC)
---
.../Transforms/SimplifyCFG/switch_create.ll | 65 +++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
index a1533bdcffb43..96b594a43c8f5 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
@@ -1125,3 +1125,68 @@ F:
ret void
}
+define void @extra_cond_is_eq_cmp(i8 %c, i32 %x) {
+; CHECK-LABEL: @extra_cond_is_eq_cmp(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 32
+; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[C:%.*]], 97
+; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP4]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i8 [[C]], 99
+; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[OR_COND]], [[CMP9]]
+; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
+; CHECK: common.ret:
+; CHECK-NEXT: ret void
+; CHECK: if.then:
+; CHECK-NEXT: tail call void @foo1()
+; CHECK-NEXT: br label [[SWITCH_EARLY_TEST]]
+;
+entry:
+ %cmp = icmp eq i32 %x, 32
+ %cmp4 = icmp eq i8 %c, 97
+ %or.cond = or i1 %cmp, %cmp4
+ %cmp9 = icmp eq i8 %c, 99
+ %or.cond11 = or i1 %or.cond, %cmp9
+ br i1 %or.cond11, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo1()
+ ret void
+
+if.end:
+ ret void
+
+}
+
+define void @extra_cond_is_eq_cmp_c(i8 %c, i32 %x) {
+; CHECK-LABEL: @extra_cond_is_eq_cmp_c(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 32
+; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 [[CMP]]
+; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
+; CHECK: switch.early.test:
+; CHECK-NEXT: switch i8 [[C:%.*]], label [[COMMON_RET:%.*]] [
+; CHECK-NEXT: i8 99, label [[IF_THEN]]
+; CHECK-NEXT: i8 97, label [[IF_THEN]]
+; CHECK-NEXT: ]
+; CHECK: common.ret:
+; CHECK-NEXT: ret void
+; CHECK: if.then:
+; CHECK-NEXT: tail call void @foo1()
+; CHECK-NEXT: br label [[COMMON_RET]]
+;
+entry:
+ %cmp = icmp eq i32 %x, 32
+ %cmp4 = icmp eq i8 %c, 97
+ %or.cond = or i1 %cmp4, %cmp
+ %cmp9 = icmp eq i8 %c, 99
+ %or.cond11 = or i1 %or.cond, %cmp9
+ br i1 %or.cond11, label %if.then, label %if.end
+
+if.then:
+ tail call void @foo1()
+ ret void
+
+if.end:
+ ret void
+
+}
>From 3153ab82a5b8817f3e745e35292fe6fcec7f3e73 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Mon, 18 Aug 2025 18:50:44 +0200
Subject: [PATCH 2/3] [SimplifyCFG] Handle that first matched eq cond in if
chain can be Extra condition.
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 19 ++++++++++++++++++-
.../Transforms/SimplifyCFG/switch_create.ll | 12 +++++++-----
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 055e8cadaab76..667bde1c978d6 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -568,9 +568,20 @@ struct ConstantComparesGatherer {
/// If the elements in Vals matches the comparisons
bool IsEq = false;
+ // Used to check if the first matched CompValue shall be the Extra check.
+ bool IgnoreFirstMatch = false;
+ bool MultipleMatches = false;
+
/// Construct and compute the result for the comparison instruction Cond
ConstantComparesGatherer(Instruction *Cond, const DataLayout &DL) : DL(DL) {
gather(Cond);
+ if (CompValue || !MultipleMatches)
+ return;
+ Extra = nullptr;
+ Vals.clear();
+ UsedICmps = 0;
+ IgnoreFirstMatch = true;
+ gather(Cond);
}
ConstantComparesGatherer(const ConstantComparesGatherer &) = delete;
@@ -581,8 +592,14 @@ struct ConstantComparesGatherer {
/// Try to set the current value used for the comparison, it succeeds only if
/// it wasn't set before or if the new value is the same as the old one
bool setValueOnce(Value *NewVal) {
- if (CompValue && CompValue != NewVal)
+ if (IgnoreFirstMatch && NewVal) {
+ IgnoreFirstMatch = false;
return false;
+ }
+ if (CompValue && CompValue != NewVal) {
+ MultipleMatches = true;
+ return false;
+ }
CompValue = NewVal;
return (CompValue != nullptr);
}
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
index 96b594a43c8f5..a06e64f74b3ac 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
@@ -1129,16 +1129,18 @@ define void @extra_cond_is_eq_cmp(i8 %c, i32 %x) {
; CHECK-LABEL: @extra_cond_is_eq_cmp(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 32
-; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[C:%.*]], 97
-; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP4]]
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i8 [[C]], 99
-; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[OR_COND]], [[CMP9]]
+; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 [[CMP]]
; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
+; CHECK: switch.early.test:
+; CHECK-NEXT: switch i8 [[C:%.*]], label [[COMMON_RET:%.*]] [
+; CHECK-NEXT: i8 99, label [[IF_THEN]]
+; CHECK-NEXT: i8 97, label [[IF_THEN]]
+; CHECK-NEXT: ]
; CHECK: common.ret:
; CHECK-NEXT: ret void
; CHECK: if.then:
; CHECK-NEXT: tail call void @foo1()
-; CHECK-NEXT: br label [[SWITCH_EARLY_TEST]]
+; CHECK-NEXT: br label [[COMMON_RET]]
;
entry:
%cmp = icmp eq i32 %x, 32
>From 289325dc74e1f8ec742cd68a16d2555a58b8d40c Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Fri, 22 Aug 2025 22:22:10 +0200
Subject: [PATCH 3/3] fixup! [SimplifyCFG] Handle that first matched eq cond in
if chain can be Extra condition.
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 667bde1c978d6..48a99543d7083 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -592,7 +592,7 @@ struct ConstantComparesGatherer {
/// Try to set the current value used for the comparison, it succeeds only if
/// it wasn't set before or if the new value is the same as the old one
bool setValueOnce(Value *NewVal) {
- if (IgnoreFirstMatch && NewVal) {
+ if (IgnoreFirstMatch) {
IgnoreFirstMatch = false;
return false;
}
@@ -601,7 +601,7 @@ struct ConstantComparesGatherer {
return false;
}
CompValue = NewVal;
- return (CompValue != nullptr);
+ return true;
}
/// Try to match Instruction "I" as a comparison against a constant and
More information about the llvm-commits
mailing list