Skip to content

Conversation

andjo403
Copy link
Contributor

Proof: https://alive2.llvm.org/ce/z/TozSD6

Noticed as a regression when I tried to add trunc nuw handling.

@llvmbot
Copy link
Member

llvmbot commented Aug 17, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Andreas Jonson (andjo403)

Changes

Proof: https://alive2.llvm.org/ce/z/TozSD6

Noticed as a regression when I tried to add trunc nuw handling.


Full diff: https://github.com/llvm/llvm-project/pull/154007.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+14)
  • (modified) llvm/test/Transforms/SimplifyCFG/switch_create.ll (+68)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 1436e479ba091..42b35c0c7e69e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -564,9 +564,19 @@ struct ConstantComparesGatherer {
   /// Number of comparisons matched in the and/or chain
   unsigned UsedICmps = 0;
 
+  // Used to check if the first matched CompValue shall be the Extra check.
+  bool IgnoreFirstMatch = false;
+
   /// Construct and compute the result for the comparison instruction Cond
   ConstantComparesGatherer(Instruction *Cond, const DataLayout &DL) : DL(DL) {
     gather(Cond);
+    if (CompValue)
+      return;
+    Extra = nullptr;
+    Vals.clear();
+    UsedICmps = 0;
+    IgnoreFirstMatch = true;
+    gather(Cond);
   }
 
   ConstantComparesGatherer(const ConstantComparesGatherer &) = delete;
@@ -577,6 +587,10 @@ 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) {
+      IgnoreFirstMatch = false;
+      return false;
+    }
     if (CompValue && CompValue != NewVal)
       return false;
     CompValue = NewVal;
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
index f446d718f8206..5f3c7b7c0fd5d 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
@@ -1068,3 +1068,71 @@ if:
 else:
   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:    [[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 %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
+
+}

@dtcxzyw
Copy link
Member

dtcxzyw commented Aug 17, 2025

@andjo403
Copy link
Contributor Author

That seems like a lot of time for the changes that it give

@andjo403
Copy link
Contributor Author

with the new commit Compile-time impact: -0.15%
but maybe shall break out the change to gather to a separat commit so it is possible to see the change in compile-time when that is merged

andjo403 added a commit that referenced this pull request Aug 18, 2025
Split out from #154007 as it
showed compile time improvements

NFC as there needs to be at least two icmps that is part of the chain.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Aug 18, 2025
…133)

Split out from llvm/llvm-project#154007 as it
showed compile time improvements

NFC as there needs to be at least two icmps that is part of the chain.
@andjo403 andjo403 force-pushed the firstmatchInstructionIsTheExtra branch from 51eec75 to 3153ab8 Compare August 18, 2025 18:17
@andjo403
Copy link
Contributor Author

a bit unclear how this is faster now Overall: -0.028% is it to small time to be significant?

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@andjo403 andjo403 merged commit ed742f8 into llvm:main Aug 23, 2025
9 checks passed
@andjo403 andjo403 deleted the firstmatchInstructionIsTheExtra branch August 23, 2025 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants