Skip to content

Commit a6b000f

Browse files
committed
[InstCombine] Keep the disjoint flag when combining two ORs if possible.
or-disjoint (or-disjoint X, C), V --> or-disjoint (or-disjoint X, V), C or-disjoint (or X, C), V --> or (or-disjoint X, V), C Proof: https://alive2.llvm.org/ce/z/wtTm5V https://alive2.llvm.org/ce/z/WC7Ai2 Signed-off-by: feng.feng <[email protected]>
1 parent 638421c commit a6b000f

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3894,12 +3894,23 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
38943894
// be simplified by a later pass either, so we try swapping the inner/outer
38953895
// ORs in the hopes that we'll be able to simplify it this way.
38963896
// (X|C) | V --> (X|V) | C
3897+
// Pass the disjoint flag in the following two patterns:
3898+
// 1. or-disjoint (or-disjoint X, C), V -->
3899+
// or-disjoint (or-disjoint X, V), C
3900+
//
3901+
// 2. or-disjoint (or X, C), V -->
3902+
// or (or-disjoint X, V), C
38973903
ConstantInt *CI;
38983904
if (Op0->hasOneUse() && !match(Op1, m_ConstantInt()) &&
38993905
match(Op0, m_Or(m_Value(A), m_ConstantInt(CI)))) {
3906+
bool IsDisjointOuter = cast<PossiblyDisjointInst>(I).isDisjoint();
3907+
bool IsDisjointInner = cast<PossiblyDisjointInst>(Op0)->isDisjoint();
39003908
Value *Inner = Builder.CreateOr(A, Op1);
3909+
cast<PossiblyDisjointInst>(Inner)->setIsDisjoint(IsDisjointOuter);
39013910
Inner->takeName(Op0);
3902-
return BinaryOperator::CreateOr(Inner, CI);
3911+
return IsDisjointOuter && IsDisjointInner
3912+
? BinaryOperator::CreateDisjointOr(Inner, CI)
3913+
: BinaryOperator::CreateOr(Inner, CI);
39033914
}
39043915

39053916
// Change (or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D))

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
define i32 @test1(i32 %x, i32 %y) {
77
; CHECK-LABEL: @test1(
8-
; CHECK-NEXT: [[INNER:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
9-
; CHECK-NEXT: [[OUTER:%.*]] = or i32 [[INNER]], 5
8+
; CHECK-NEXT: [[INNER:%.*]] = or disjoint i32 [[X:%.*]], [[Y:%.*]]
9+
; CHECK-NEXT: [[OUTER:%.*]] = or disjoint i32 [[INNER]], 5
1010
; CHECK-NEXT: ret i32 [[OUTER]]
1111
;
1212
%inner = or disjoint i32 %x, 5
@@ -16,7 +16,7 @@ define i32 @test1(i32 %x, i32 %y) {
1616

1717
define i32 @test2(i32 %x, i32 %y) {
1818
; CHECK-LABEL: @test2(
19-
; CHECK-NEXT: [[INNER:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
19+
; CHECK-NEXT: [[INNER:%.*]] = or disjoint i32 [[X:%.*]], [[Y:%.*]]
2020
; CHECK-NEXT: [[OUTER:%.*]] = or i32 [[INNER]], 5
2121
; CHECK-NEXT: ret i32 [[OUTER]]
2222
;

0 commit comments

Comments
 (0)