[llvm] [GISel] import pattern `(A-(B-C)) to A+(C-B)` (PR #181676)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 16 09:46:21 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Luisa Cicolini (luisacicolini)
<details>
<summary>Changes</summary>
This PR imports the rewrite pattern `(A-(B-C)) to A+(C-B)` from selectionDAG to GlobalISel.
The rewrite should only trigger when `B-C` is used once.
---
Full diff: https://github.com/llvm/llvm-project/pull/181676.diff
4 Files Affected:
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+10)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir (+54)
- (modified) llvm/test/CodeGen/AArch64/neg-selects.ll (+1-3)
- (modified) llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll (+2-2)
``````````diff
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index f5c940bffc8fb..ab0044693de13 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1938,6 +1938,15 @@ def APlusBMinusAplusC : GICombineRule<
(G_SUB $sub1, $B, $add1),
(G_ADD $root, $A, $sub1)),
(apply (G_SUB $root, $B, $C))>;
+
+// fold (A-(B-C)) to A+(C-B)
+def AMinusBMinusC : GICombineRule<
+ (defs root:$root),
+ (match (G_SUB $sub1, $B, $C),
+ (G_SUB $root, $A, $sub1),
+ [{ return MRI.hasOneNonDBGUse(${sub1}.getReg()); }]),
+ (apply (G_SUB $add, $C, $B),
+ (G_ADD $root, $A, $add))>;
// fold (A+(B-(C+A))) to (B-C)
def APlusBMinusCPlusA : GICombineRule<
@@ -2007,6 +2016,7 @@ def integer_reassoc_combines: GICombineGroup<[
AMinusBPlusCMinusA,
AMinusBPlusBMinusC,
APlusBMinusAplusC,
+ AMinusBMinusC,
APlusBMinusCPlusA,
APlusC1MinusC2,
C2MinusAPlusC1,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
index c9b24ad75ce27..9195cce51ac6f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-integer.mir
@@ -413,3 +413,57 @@ body: |
$x0 = COPY %add
RET_ReallyLR implicit $x0
+...
+---
+name: AMinusBMinusC_oneUse
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+
+ ; CHECK-LABEL: name: AMinusBMinusC_oneUse
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(s64) = COPY $x0
+ ; CHECK-NEXT: %b:_(s64) = COPY $x1
+ ; CHECK-NEXT: %c:_(s64) = COPY $x2
+ ; CHECK-NEXT: %sub1:_(s64) = G_SUB %b, %c
+ ; CHECK-NEXT: %sub2:_(s64) = G_SUB %a, %sub1
+ ; CHECK-NEXT: %mul:_(s64) = G_MUL %sub2, %sub1
+ ; CHECK-NEXT: $x0 = COPY %mul(s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(s64) = COPY $x0
+ %b:_(s64) = COPY $x1
+ %c:_(s64) = COPY $x2
+ %sub1:_(s64) = G_SUB %b, %c
+ %sub2:_(s64) = G_SUB %a, %sub1
+ %mul:_(s64) = G_MUL %sub2, %sub1
+ $x0 = COPY %mul
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: AMinusBMinusC
+body: |
+ bb.0:
+ liveins: $x0, $x1, $x2
+
+
+ ; CHECK-LABEL: name: AMinusBMinusC
+ ; CHECK: liveins: $x0, $x1, $x2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(s64) = COPY $x0
+ ; CHECK-NEXT: %b:_(s64) = COPY $x1
+ ; CHECK-NEXT: %c:_(s64) = COPY $x2
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB %c, %b
+ ; CHECK-NEXT: %sub2:_(s64) = G_ADD %a, [[SUB]]
+ ; CHECK-NEXT: $x0 = COPY %sub2(s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %a:_(s64) = COPY $x0
+ %b:_(s64) = COPY $x1
+ %c:_(s64) = COPY $x2
+ %sub1:_(s64) = G_SUB %b, %c
+ %sub2:_(s64) = G_SUB %a, %sub1
+ $x0 = COPY %sub2
+ RET_ReallyLR implicit $x0
+
diff --git a/llvm/test/CodeGen/AArch64/neg-selects.ll b/llvm/test/CodeGen/AArch64/neg-selects.ll
index b643ee7670e42..f656fc2e62040 100644
--- a/llvm/test/CodeGen/AArch64/neg-selects.ll
+++ b/llvm/test/CodeGen/AArch64/neg-selects.ll
@@ -35,9 +35,7 @@ define i32 @negneg_select_nega(i32 %a, i32 %b, i1 %bb) {
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: and w8, w2, #0x1
; CHECK-GI-NEXT: tst w8, #0x1
-; CHECK-GI-NEXT: csneg w8, w1, w0, eq
-; CHECK-GI-NEXT: neg w8, w8
-; CHECK-GI-NEXT: neg w0, w8
+; CHECK-GI-NEXT: csneg w0, w1, w0, eq
; CHECK-GI-NEXT: ret
%nega = sub i32 0, %a
%sel = select i1 %bb, i32 %nega, i32 %b
diff --git a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
index 01aea72d77114..8ce2e520cef83 100644
--- a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
@@ -2849,9 +2849,9 @@ define <8 x i16> @pr149380(<4 x i16> %u1, <1 x i64> %u2, <8 x i16> %vqshlu_n169)
; CHECK-GI-LABEL: pr149380:
; CHECK-GI: // %bb.0: // %entry
; CHECK-GI-NEXT: movi v0.2d, #0xffffffffffffffff
-; CHECK-GI-NEXT: neg v1.8h, v2.8h
+; CHECK-GI-NEXT: movi v1.2d, #0000000000000000
; CHECK-GI-NEXT: movi v3.8h, #1
-; CHECK-GI-NEXT: neg v1.8h, v1.8h
+; CHECK-GI-NEXT: add v1.8h, v1.8h, v2.8h
; CHECK-GI-NEXT: sub v0.8h, v0.8h, v2.8h
; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b
; CHECK-GI-NEXT: and v0.16b, v0.16b, v3.16b
``````````
</details>
https://github.com/llvm/llvm-project/pull/181676
More information about the llvm-commits
mailing list