1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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
This commit is contained in:
David Green 2021-07-07 10:21:07 +01:00
parent 5e3e34426a
commit 13a750213e
5 changed files with 41 additions and 35 deletions

View File

@ -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)))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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