summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp7
-rw-r--r--llvm/test/CodeGen/AArch64/sink-addsub-of-const.ll2
-rw-r--r--llvm/test/CodeGen/X86/sink-addsub-of-const.ll4
3 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 43899ecb8e6..efac27a1b69 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2957,6 +2957,13 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, N1.getOperand(0));
return DAG.getNode(ISD::SUB, DL, VT, Sub, N1.getOperand(1));
}
+ // (x - C) - y -> (x - y) - C
+ // This is necessary because SUB(X,C) -> ADD(X,-C) doesn't work for vectors.
+ if (N0.hasOneUse() && N0.getOpcode() == ISD::SUB &&
+ isConstantOrConstantVector(N0.getOperand(1))) {
+ SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0.getOperand(0), N1);
+ return DAG.getNode(ISD::SUB, DL, VT, Sub, N0.getOperand(1));
+ }
// If the target's bool is represented as 0/-1, prefer to make this 'add 0/-1'
// rather than 'sub 0/1' (the sext should get folded).
diff --git a/llvm/test/CodeGen/AArch64/sink-addsub-of-const.ll b/llvm/test/CodeGen/AArch64/sink-addsub-of-const.ll
index 7c9ae43db13..0e1a426c77f 100644
--- a/llvm/test/CodeGen/AArch64/sink-addsub-of-const.ll
+++ b/llvm/test/CodeGen/AArch64/sink-addsub-of-const.ll
@@ -314,8 +314,8 @@ define <4 x i32> @vec_sink_sub_of_const_to_sub(<4 x i32> %a, <4 x i32> %b, <4 x
; CHECK-NEXT: adrp x8, .LCPI20_0
; CHECK-NEXT: ldr q3, [x8, :lo12:.LCPI20_0]
; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s
-; CHECK-NEXT: sub v0.4s, v0.4s, v3.4s
; CHECK-NEXT: sub v0.4s, v0.4s, v2.4s
+; CHECK-NEXT: sub v0.4s, v0.4s, v3.4s
; CHECK-NEXT: ret
%t0 = sub <4 x i32> %a, %b
%t1 = sub <4 x i32> %t0, <i32 42, i32 24, i32 undef, i32 46>
diff --git a/llvm/test/CodeGen/X86/sink-addsub-of-const.ll b/llvm/test/CodeGen/X86/sink-addsub-of-const.ll
index 3bca6d1d199..4544707d07a 100644
--- a/llvm/test/CodeGen/X86/sink-addsub-of-const.ll
+++ b/llvm/test/CodeGen/X86/sink-addsub-of-const.ll
@@ -460,15 +460,15 @@ define <4 x i32> @vec_sink_sub_of_const_to_sub(<4 x i32> %a, <4 x i32> %b, <4 x
; X32-LABEL: vec_sink_sub_of_const_to_sub:
; X32: # %bb.0:
; X32-NEXT: psubd %xmm1, %xmm0
-; X32-NEXT: psubd {{\.LCPI.*}}, %xmm0
; X32-NEXT: psubd %xmm2, %xmm0
+; X32-NEXT: psubd {{\.LCPI.*}}, %xmm0
; X32-NEXT: retl
;
; X64-LABEL: vec_sink_sub_of_const_to_sub:
; X64: # %bb.0:
; X64-NEXT: psubd %xmm1, %xmm0
-; X64-NEXT: psubd {{.*}}(%rip), %xmm0
; X64-NEXT: psubd %xmm2, %xmm0
+; X64-NEXT: psubd {{.*}}(%rip), %xmm0
; X64-NEXT: retq
%t0 = sub <4 x i32> %a, %b
%t1 = sub <4 x i32> %t0, <i32 42, i32 24, i32 undef, i32 46>
OpenPOWER on IntegriCloud