[PATCH] D148341: [DAGCombiner] Fold add (mul x, C), x to mul x, C+1
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 14 07:17:08 PDT 2023
nikic created this revision.
nikic added reviewers: RKSimon, pengfei, goldstein.w.n.
Herald added subscribers: StephenFan, ecnelises, hiraditya.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
While this is normally non-canonical IR, this pattern can appear during SDAG lowering if the `add` is actually a `getelementptr`, as illustrated in `@test_ptr`. This pattern comes up when doing provenance-aware high-bit pointer tagging.
Proof: https://alive2.llvm.org/ce/z/DLoEcs
https://reviews.llvm.org/D148341
Files:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/AArch64/arm64-promote-const.ll
llvm/test/CodeGen/X86/add-of-mul.ll
Index: llvm/test/CodeGen/X86/add-of-mul.ll
===================================================================
--- llvm/test/CodeGen/X86/add-of-mul.ll
+++ llvm/test/CodeGen/X86/add-of-mul.ll
@@ -5,19 +5,28 @@
; CHECK-LABEL: test_scalar:
; CHECK: # %bb.0:
; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
-; CHECK-NEXT: leal (%rdi,%rdi,2), %eax
-; CHECK-NEXT: addl %edi, %eax
+; CHECK-NEXT: leal (,%rdi,4), %eax
; CHECK-NEXT: retq
%mul = mul i32 %x, 3
%add = add i32 %mul, %x
ret i32 %add
}
+define i32 @test_scalar_commuted(i32 %x) {
+; CHECK-LABEL: test_scalar_commuted:
+; CHECK: # %bb.0:
+; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT: leal (,%rdi,4), %eax
+; CHECK-NEXT: retq
+ %mul = mul i32 %x, 3
+ %add = add i32 %x, %mul
+ ret i32 %add
+}
+
define <4 x i32> @test_vector(<4 x i32> %x) {
; CHECK-LABEL: test_vector:
; CHECK: # %bb.0:
-; CHECK-NEXT: paddd %xmm0, %xmm0
-; CHECK-NEXT: paddd %xmm0, %xmm0
+; CHECK-NEXT: pslld $2, %xmm0
; CHECK-NEXT: retq
%mul = mul <4 x i32> %x, <i32 3, i32 3, i32 3, i32 3>
%add = add <4 x i32> %mul, %x
@@ -27,8 +36,7 @@
define ptr @test_ptr(ptr %p) {
; CHECK-LABEL: test_ptr:
; CHECK: # %bb.0:
-; CHECK-NEXT: leaq (%rdi,%rdi,2), %rax
-; CHECK-NEXT: addq %rdi, %rax
+; CHECK-NEXT: leaq (,%rdi,4), %rax
; CHECK-NEXT: retq
%addr = ptrtoint ptr %p to i64
%mul = mul i64 %addr, 3
Index: llvm/test/CodeGen/AArch64/arm64-promote-const.ll
===================================================================
--- llvm/test/CodeGen/AArch64/arm64-promote-const.ll
+++ llvm/test/CodeGen/AArch64/arm64-promote-const.ll
@@ -44,7 +44,7 @@
; PROMOTED: ldr q[[REGNUM:[0-9]+]], [[[PAGEADDR]], [[CSTV1]]@PAGEOFF]
; Destination register is defined by ABI
; PROMOTED-NEXT: add.16b v0, v0, v[[REGNUM]]
-; PROMOTED-NEXT: mla.16b v0, v0, v[[REGNUM]]
+; PROMOTED-NEXT: mls.16b v0, v0, v[[REGNUM]]
; PROMOTED-NEXT: ret
; REGULAR-LABEL: test2:
@@ -55,12 +55,12 @@
; REGULAR: ldr q[[REGNUM:[0-9]+]], [[[PAGEADDR]], [[CSTLABEL]]@PAGEOFF]
; Destination register is defined by ABI
; REGULAR-NEXT: add.16b v0, v0, v[[REGNUM]]
-; REGULAR-NEXT: mla.16b v0, v0, v[[REGNUM]]
+; REGULAR-NEXT: mls.16b v0, v0, v[[REGNUM]]
; REGULAR-NEXT: ret
%add.i = add <16 x i8> %arg, <i8 -40, i8 -93, i8 -118, i8 -99, i8 -75, i8 -105, i8 74, i8 -110, i8 62, i8 -115, i8 -119, i8 -120, i8 34, i8 -124, i8 0, i8 -128>
%mul.i = mul <16 x i8> %add.i, <i8 -40, i8 -93, i8 -118, i8 -99, i8 -75, i8 -105, i8 74, i8 -110, i8 62, i8 -115, i8 -119, i8 -120, i8 34, i8 -124, i8 0, i8 -128>
- %add.i9 = add <16 x i8> %add.i, %mul.i
- ret <16 x i8> %add.i9
+ %sub.i9 = sub <16 x i8> %add.i, %mul.i
+ ret <16 x i8> %sub.i9
}
; Two different uses of the same constant in two different basic blocks,
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3058,6 +3058,15 @@
}
}
+ // add (mul x, C), x -> mul x, C+1
+ if (N0.getOpcode() == ISD::MUL && N0.getOperand(0) == N1 &&
+ isConstantOrConstantVector(N0.getOperand(1), /*NoOpaques=*/true) &&
+ N0.hasOneUse()) {
+ SDValue NewC = DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(1),
+ DAG.getConstant(1, DL, VT));
+ return DAG.getNode(ISD::MUL, DL, VT, N0.getOperand(0), NewC);
+ }
+
// If the target's bool is represented as 0/1, prefer to make this 'sub 0/1'
// rather than 'add 0/-1' (the zext should get folded).
// add (sext i1 Y), X --> sub X, (zext i1 Y)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148341.513576.patch
Type: text/x-patch
Size: 3681 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230414/4db69d37/attachment.bin>
More information about the llvm-commits
mailing list