[llvm] e7bf750 - [InstCombine] Pass disjoint in or combine (#138800)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 7 23:29:17 PDT 2025


Author: fengfeng
Date: 2025-05-08T14:29:13+08:00
New Revision: e7bf75043701119f8aeecff4c203cbcf2266fa62

URL: https://github.com/llvm/llvm-project/commit/e7bf75043701119f8aeecff4c203cbcf2266fa62
DIFF: https://github.com/llvm/llvm-project/commit/e7bf75043701119f8aeecff4c203cbcf2266fa62.diff

LOG: [InstCombine] Pass disjoint in or combine (#138800)

Proof: https://alive2.llvm.org/ce/z/wtTm5V
https://alive2.llvm.org/ce/z/WC7Ai2

---------

Signed-off-by: feng.feng <feng.feng at iluvatar.com>

Added: 
    llvm/test/Transforms/InstCombine/or-or-combine.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 100c144c177fe..508aef63a3128 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3894,12 +3894,23 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
   // be simplified by a later pass either, so we try swapping the inner/outer
   // ORs in the hopes that we'll be able to simplify it this way.
   // (X|C) | V --> (X|V) | C
+  // Pass the disjoint flag in the following two patterns:
+  // 1. or-disjoint (or-disjoint X, C), V -->
+  //    or-disjoint (or-disjoint X, V), C
+  //
+  // 2. or-disjoint (or X, C), V -->
+  //    or (or-disjoint X, V), C
   ConstantInt *CI;
   if (Op0->hasOneUse() && !match(Op1, m_ConstantInt()) &&
       match(Op0, m_Or(m_Value(A), m_ConstantInt(CI)))) {
+    bool IsDisjointOuter = cast<PossiblyDisjointInst>(I).isDisjoint();
+    bool IsDisjointInner = cast<PossiblyDisjointInst>(Op0)->isDisjoint();
     Value *Inner = Builder.CreateOr(A, Op1);
+    cast<PossiblyDisjointInst>(Inner)->setIsDisjoint(IsDisjointOuter);
     Inner->takeName(Op0);
-    return BinaryOperator::CreateOr(Inner, CI);
+    return IsDisjointOuter && IsDisjointInner
+               ? BinaryOperator::CreateDisjointOr(Inner, CI)
+               : BinaryOperator::CreateOr(Inner, CI);
   }
 
   // Change (or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D))

diff  --git a/llvm/test/Transforms/InstCombine/or-or-combine.ll b/llvm/test/Transforms/InstCombine/or-or-combine.ll
new file mode 100644
index 0000000000000..9dc0dcc29b2f2
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/or-or-combine.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+; (X | C) | Y --> (X | Y) | C
+
+define i32 @test1(i32 %x, i32 %y) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:    [[INNER:%.*]] = or disjoint i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[OUTER:%.*]] = or disjoint i32 [[INNER]], 5
+; CHECK-NEXT:    ret i32 [[OUTER]]
+;
+  %inner = or disjoint i32 %x, 5
+  %outer = or disjoint i32 %inner, %y
+  ret i32 %outer
+}
+
+define i32 @test2(i32 %x, i32 %y) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT:    [[INNER:%.*]] = or disjoint i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[OUTER:%.*]] = or i32 [[INNER]], 5
+; CHECK-NEXT:    ret i32 [[OUTER]]
+;
+  %inner = or i32 %x, 5
+  %outer = or disjoint i32 %inner, %y
+  ret i32 %outer
+}
+
+define i32 @test3(i32 %x, i32 %y) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT:    [[INNER:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[OUTER:%.*]] = or i32 [[INNER]], 5
+; CHECK-NEXT:    ret i32 [[OUTER]]
+;
+  %inner = or disjoint i32 %x, 5
+  %outer = or i32 %inner, %y
+  ret i32 %outer
+}
+
+define i32 @test4(i32 %x, i32 %y) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT:    [[INNER:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[OUTER:%.*]] = or i32 [[INNER]], 5
+; CHECK-NEXT:    ret i32 [[OUTER]]
+;
+  %inner = or i32 %x, 5
+  %outer = or i32 %inner, %y
+  ret i32 %outer
+}


        


More information about the llvm-commits mailing list