[llvm] 4ce26de - [DAG] Reassociate Add with Or

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 7 02:21:19 PDT 2021


Author: David Green
Date: 2021-07-07T10:21:07+01:00
New Revision: 4ce26deac2a69492d5af349c25f285f6d493f82c

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

LOG: [DAG] Reassociate Add with Or

We already have reassociation code for Adds and Ors separately in DAG
combiner, this adds it for the combination of the two where Ors act like
Adds. It reassociates (add (or (x, c), y) -> (add (add (x, y), c)) where
we know that the Ors operands have no common bits set, and the Or has
one use.

Differential Revision: https://reviews.llvm.org/D104765

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/test/CodeGen/ARM/add-like-or.ll
    llvm/test/CodeGen/Hexagon/isel-global-offset-alignment.ll
    llvm/test/CodeGen/SystemZ/addr-01.ll
    llvm/test/CodeGen/SystemZ/addr-02.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c8878bbfaf7b5..f02d7621959a5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2338,6 +2338,23 @@ SDValue DAGCombiner::visitADDLike(SDNode *N) {
   if (!reassociationCanBreakAddressingModePattern(ISD::ADD, DL, N0, N1)) {
     if (SDValue RADD = reassociateOps(ISD::ADD, DL, N0, N1, N->getFlags()))
       return RADD;
+
+    // Reassociate (add (or x, c), y) -> (add add(x, y), c)) if (or x, c) is
+    // equivalent to (add x, c).
+    auto ReassociateAddOr = [&](SDValue N0, SDValue N1) {
+      if (N0.getOpcode() == ISD::OR && N0.hasOneUse() &&
+          isConstantOrConstantVector(N0.getOperand(1), /* NoOpaque */ true) &&
+          DAG.haveNoCommonBitsSet(N0.getOperand(0), N0.getOperand(1))) {
+        return DAG.getNode(ISD::ADD, DL, VT,
+                           DAG.getNode(ISD::ADD, DL, VT, N1, N0.getOperand(0)),
+                           N0.getOperand(1));
+      }
+      return SDValue();
+    };
+    if (SDValue Add = ReassociateAddOr(N0, N1))
+      return Add;
+    if (SDValue Add = ReassociateAddOr(N1, N0))
+      return Add;
   }
   // fold ((0-A) + B) -> B-A
   if (N0.getOpcode() == ISD::SUB && isNullOrNullSplat(N0.getOperand(0)))

diff  --git a/llvm/test/CodeGen/ARM/add-like-or.ll b/llvm/test/CodeGen/ARM/add-like-or.ll
index 943917960662f..20d3ba398e16f 100644
--- a/llvm/test/CodeGen/ARM/add-like-or.ll
+++ b/llvm/test/CodeGen/ARM/add-like-or.ll
@@ -162,22 +162,20 @@ define i32 @oradd(i32 %i, i32 %y) {
 ; CHECK-T1-LABEL: oradd:
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    lsls r0, r0, #1
+; CHECK-T1-NEXT:    adds r0, r1, r0
 ; CHECK-T1-NEXT:    adds r0, r0, #1
-; CHECK-T1-NEXT:    adds r0, r0, r1
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: oradd:
 ; CHECK-T2:       @ %bb.0: @ %entry
-; CHECK-T2-NEXT:    lsls r0, r0, #1
+; CHECK-T2-NEXT:    add.w r0, r1, r0, lsl #1
 ; CHECK-T2-NEXT:    adds r0, #1
-; CHECK-T2-NEXT:    add r0, r1
 ; CHECK-T2-NEXT:    bx lr
 ;
 ; CHECK-A-LABEL: oradd:
 ; CHECK-A:       @ %bb.0: @ %entry
-; CHECK-A-NEXT:    mov r2, #1
-; CHECK-A-NEXT:    orr r0, r2, r0, lsl #1
-; CHECK-A-NEXT:    add r0, r0, r1
+; CHECK-A-NEXT:    add r0, r1, r0, lsl #1
+; CHECK-A-NEXT:    add r0, r0, #1
 ; CHECK-A-NEXT:    bx lr
 entry:
   %mul = shl i32 %i, 1
@@ -190,22 +188,20 @@ define i32 @orgep(i32 %i, i32* %x, i32* %y) {
 ; CHECK-T1-LABEL: orgep:
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    lsls r0, r0, #3
-; CHECK-T1-NEXT:    adds r0, r0, #4
-; CHECK-T1-NEXT:    ldr r0, [r1, r0]
+; CHECK-T1-NEXT:    adds r0, r1, r0
+; CHECK-T1-NEXT:    ldr r0, [r0, #4]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: orgep:
 ; CHECK-T2:       @ %bb.0: @ %entry
-; CHECK-T2-NEXT:    lsls r0, r0, #3
-; CHECK-T2-NEXT:    adds r0, #4
-; CHECK-T2-NEXT:    ldr r0, [r1, r0]
+; CHECK-T2-NEXT:    add.w r0, r1, r0, lsl #3
+; CHECK-T2-NEXT:    ldr r0, [r0, #4]
 ; CHECK-T2-NEXT:    bx lr
 ;
 ; CHECK-A-LABEL: orgep:
 ; CHECK-A:       @ %bb.0: @ %entry
-; CHECK-A-NEXT:    mov r2, #4
-; CHECK-A-NEXT:    orr r0, r2, r0, lsl #3
-; CHECK-A-NEXT:    ldr r0, [r1, r0]
+; CHECK-A-NEXT:    add r0, r1, r0, lsl #3
+; CHECK-A-NEXT:    ldr r0, [r0, #4]
 ; CHECK-A-NEXT:    bx lr
 entry:
   %mul = shl i32 %i, 1
@@ -219,31 +215,24 @@ define i32 @orgeps(i32 %i, i32* %x, i32* %y) {
 ; CHECK-T1-LABEL: orgeps:
 ; CHECK-T1:       @ %bb.0: @ %entry
 ; CHECK-T1-NEXT:    lsls r0, r0, #3
-; CHECK-T1-NEXT:    adds r2, r0, #4
-; CHECK-T1-NEXT:    ldr r2, [r1, r2]
-; CHECK-T1-NEXT:    adds r0, r0, r1
+; CHECK-T1-NEXT:    adds r0, r1, r0
+; CHECK-T1-NEXT:    ldr r1, [r0, #4]
 ; CHECK-T1-NEXT:    ldr r0, [r0, #8]
-; CHECK-T1-NEXT:    adds r0, r0, r2
+; CHECK-T1-NEXT:    adds r0, r0, r1
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: orgeps:
 ; CHECK-T2:       @ %bb.0: @ %entry
-; CHECK-T2-NEXT:    lsls r2, r0, #3
 ; CHECK-T2-NEXT:    add.w r0, r1, r0, lsl #3
-; CHECK-T2-NEXT:    adds r2, #4
-; CHECK-T2-NEXT:    ldr r0, [r0, #8]
-; CHECK-T2-NEXT:    ldr r2, [r1, r2]
-; CHECK-T2-NEXT:    add r0, r2
+; CHECK-T2-NEXT:    ldrd r0, r1, [r0, #4]
+; CHECK-T2-NEXT:    add r0, r1
 ; CHECK-T2-NEXT:    bx lr
 ;
 ; CHECK-A-LABEL: orgeps:
 ; CHECK-A:       @ %bb.0: @ %entry
-; CHECK-A-NEXT:    mov r2, #4
-; CHECK-A-NEXT:    orr r2, r2, r0, lsl #3
 ; CHECK-A-NEXT:    add r0, r1, r0, lsl #3
-; CHECK-A-NEXT:    ldr r2, [r1, r2]
-; CHECK-A-NEXT:    ldr r0, [r0, #8]
-; CHECK-A-NEXT:    add r0, r0, r2
+; CHECK-A-NEXT:    ldrd r0, r1, [r0, #4]
+; CHECK-A-NEXT:    add r0, r1, r0
 ; CHECK-A-NEXT:    bx lr
 entry:
   %mul = shl i32 %i, 1

diff  --git a/llvm/test/CodeGen/Hexagon/isel-global-offset-alignment.ll b/llvm/test/CodeGen/Hexagon/isel-global-offset-alignment.ll
index 4ee18c4a2358f..bd170d89e4131 100644
--- a/llvm/test/CodeGen/Hexagon/isel-global-offset-alignment.ll
+++ b/llvm/test/CodeGen/Hexagon/isel-global-offset-alignment.ll
@@ -14,13 +14,13 @@ define void @fred(i1 %x) #0 {
 ; CHECK:       // %bb.0: // %b0
 ; CHECK-NEXT:    {
 ; CHECK-NEXT:     p0 = tstbit(r0,#0)
+; CHECK-NEXT:     if (!p0.new) r2 = #1024
+; CHECK-NEXT:     if (p0.new) r2 = #0
 ; CHECK-NEXT:     r5:4 = combine(#0,#0)
-; CHECK-NEXT:     if (p0.new) r2 = #2
-; CHECK-NEXT:     if (!p0.new) r2 = #1026
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
-; CHECK-NEXT:     memd(r2+##array+182) = r5:4
-; CHECK-NEXT:     memd(r2+##array+174) = r5:4
+; CHECK-NEXT:     memd(r2+##array+184) = r5:4
+; CHECK-NEXT:     memd(r2+##array+176) = r5:4
 ; CHECK-NEXT:    }
 ; CHECK-NEXT:    {
 ; CHECK-NEXT:     jumpr r31

diff  --git a/llvm/test/CodeGen/SystemZ/addr-01.ll b/llvm/test/CodeGen/SystemZ/addr-01.ll
index 373fc578db831..c98b0523794a8 100644
--- a/llvm/test/CodeGen/SystemZ/addr-01.ll
+++ b/llvm/test/CodeGen/SystemZ/addr-01.ll
@@ -73,7 +73,7 @@ define void @f6(i64 %addr, i64 %index) {
 ; CHECK-LABEL: f6:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    nill %r2, 65528
-; CHECK-NEXT:    lb %r0, 6(%r3,%r2)
+; CHECK-NEXT:    lb %r0, 6(%r2,%r3)
 ; CHECK-NEXT:    br %r14
   %aligned = and i64 %addr, -8
   %or = or i64 %aligned, 6

diff  --git a/llvm/test/CodeGen/SystemZ/addr-02.ll b/llvm/test/CodeGen/SystemZ/addr-02.ll
index 615d35c8b9407..d9e1907dc6da1 100644
--- a/llvm/test/CodeGen/SystemZ/addr-02.ll
+++ b/llvm/test/CodeGen/SystemZ/addr-02.ll
@@ -89,8 +89,8 @@ define void @f6(i64 %addr, i64 %index, i8 **%dst) {
 ; CHECK-LABEL: f6:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    nill %r2, 65528
-; CHECK-NEXT:    lb %r0, 6(%r3,%r2)
-; CHECK-NEXT:    la %r0, 6(%r3,%r2)
+; CHECK-NEXT:    lb %r0, 6(%r2,%r3)
+; CHECK-NEXT:    la %r0, 6(%r2,%r3)
 ; CHECK-NEXT:    stg %r0, 0(%r4)
 ; CHECK-NEXT:    br %r14
   %aligned = and i64 %addr, -8


        


More information about the llvm-commits mailing list