[llvm] GlobalISel: neg (and x, 1) --> SIGN_EXTEND_INREG x, 1 (PR #131367)
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 31 11:57:39 PDT 2025
https://github.com/MatzeB updated https://github.com/llvm/llvm-project/pull/131367
>From d9a25546ac7aa9a7d719e584fb244de944a1fa8c Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Fri, 14 Mar 2025 10:36:46 -0700
Subject: [PATCH 1/3] GlobalISel: neg (and x, 1) --> SIGN_EXTEND_INREG x, 1
---
.../include/llvm/Target/GlobalISel/Combine.td | 12 ++++++++++-
.../combine-neg-and-one-to-sext-inreg.mir | 20 +++++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3590ab221ad44..d43046ec5d282 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -747,6 +747,16 @@ def shl_ashr_to_sext_inreg : GICombineRule<
(apply [{ Helper.applyAshShlToSextInreg(*${root}, ${info});}])
>;
+// Fold sub 0, (and x, 1) -> sext_inreg x, 1
+def neg_and_one_to_sext_inreg : GICombineRule<
+ (defs root:$dst),
+ (match (G_AND $and, $x, 1),
+ (G_SUB $dst, 0, $and),
+ [{ return Helper.isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_SEXT_INREG, {MRI.getType(${x}.getReg())}}); }]),
+ (apply (G_SEXT_INREG $dst, $x, 1))
+>;
+
// Fold and(and(x, C1), C2) -> C1&C2 ? and(x, C1&C2) : 0
def overlapping_and: GICombineRule <
(defs root:$root, build_fn_matchinfo:$info),
@@ -2013,7 +2023,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
undef_combines, identity_combines, phi_combines,
simplify_add_to_sub, hoist_logic_op_with_same_opcode_hands, shifts_too_big,
reassocs, ptr_add_immed_chain, cmp_combines,
- shl_ashr_to_sext_inreg, sext_inreg_of_load,
+ shl_ashr_to_sext_inreg, neg_and_one_to_sext_inreg, sext_inreg_of_load,
width_reduction_combines, select_combines,
known_bits_simplifications, trunc_shift,
not_cmp_fold, opt_brcond_by_inverting_cond,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
new file mode 100644
index 0000000000000..aeb7ec3d9b9ee
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
@@ -0,0 +1,20 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -o - -mtriple aarch64-- -run-pass=aarch64-prelegalizer-combiner %s | FileCheck %s
+---
+name: test_combine_neg_and_one_to_sext_inreg
+body: |
+ bb.1:
+ liveins: $w0
+ ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 1
+ ; CHECK-NEXT: $w0 = COPY [[SEXT_INREG]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 1
+ %3:_(s32) = G_CONSTANT i32 0
+ %2:_(s32) = G_AND %0:_, %1:_
+ %4:_(s32) = G_SUB %3:_, %2:_
+ $w0 = COPY %4:_(s32)
+...
>From 4ddc23d18a005b618e6d03d6b198b30e3e05f89e Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Mon, 17 Mar 2025 10:59:46 -0700
Subject: [PATCH 2/3] address review comments
---
.../include/llvm/Target/GlobalISel/Combine.td | 5 +-
.../combine-neg-and-one-to-sext-inreg.mir | 63 +++++++++++++++----
.../combine-neg-and-one-to-sext-inreg.mir | 22 +++++++
3 files changed, 77 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index d43046ec5d282..6d5f5f7d43703 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -752,8 +752,9 @@ def neg_and_one_to_sext_inreg : GICombineRule<
(defs root:$dst),
(match (G_AND $and, $x, 1),
(G_SUB $dst, 0, $and),
- [{ return Helper.isLegalOrBeforeLegalizer(
- {TargetOpcode::G_SEXT_INREG, {MRI.getType(${x}.getReg())}}); }]),
+ [{ return MRI.hasOneNonDBGUse(${and}.getReg()) &&
+ Helper.isLegalOrBeforeLegalizer(
+ {TargetOpcode::G_SEXT_INREG, {MRI.getType(${x}.getReg())}}); }]),
(apply (G_SEXT_INREG $dst, $x, 1))
>;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
index aeb7ec3d9b9ee..b0d7de9b3f2d5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
@@ -1,20 +1,61 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
# RUN: llc -o - -mtriple aarch64-- -run-pass=aarch64-prelegalizer-combiner %s | FileCheck %s
---
-name: test_combine_neg_and_one_to_sext_inreg
+name: test_combine_neg_and_one_to_sext_inreg_s32
body: |
bb.1:
liveins: $w0
- ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg
+ ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg_s32
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
- ; CHECK-NEXT: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY]], 1
- ; CHECK-NEXT: $w0 = COPY [[SEXT_INREG]](s32)
- %0:_(s32) = COPY $w0
- %1:_(s32) = G_CONSTANT i32 1
- %3:_(s32) = G_CONSTANT i32 0
- %2:_(s32) = G_AND %0:_, %1:_
- %4:_(s32) = G_SUB %3:_, %2:_
- $w0 = COPY %4:_(s32)
+ ; CHECK-NEXT: %x:_(s32) = COPY $w0
+ ; CHECK-NEXT: %res:_(s32) = G_SEXT_INREG %x, 1
+ ; CHECK-NEXT: $w0 = COPY %res(s32)
+ %x:_(s32) = COPY $w0
+ %one:_(s32) = G_CONSTANT i32 1
+ %zero:_(s32) = G_CONSTANT i32 0
+ %and:_(s32) = G_AND %x:_, %one:_
+ %res:_(s32) = G_SUB %zero:_, %and:_
+ $w0 = COPY %res:_(s32)
+...
+---
+name: test_combine_neg_and_one_to_sext_inreg_s64
+body: |
+ bb.1:
+ liveins: $x0
+ ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg_s64
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s64) = COPY $x0
+ ; CHECK-NEXT: %res:_(s64) = G_SEXT_INREG %x, 1
+ ; CHECK-NEXT: $x0 = COPY %res(s64)
+ %x:_(s64) = COPY $x0
+ %one:_(s64) = G_CONSTANT i64 1
+ %zero:_(s64) = G_CONSTANT i64 0
+ %and:_(s64) = G_AND %x:_, %one:_
+ %res:_(s64) = G_SUB %zero:_, %and:_
+ $x0 = COPY %res:_(s64)
+...
+---
+name: test_combine_neg_and_one_to_sext_inreg_multiuse_should_not_transform
+body: |
+ bb.1:
+ liveins: $x0
+ ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg_multiuse_should_not_transform
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s64) = COPY $x0
+ ; CHECK-NEXT: %one:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: %and:_(s64) = G_AND %x, %one
+ ; CHECK-NEXT: %res:_(s64) = G_SUB %zero, %and
+ ; CHECK-NEXT: $x0 = COPY %res(s64)
+ ; CHECK-NEXT: $x1 = COPY %and(s64)
+ %x:_(s64) = COPY $x0
+ %one:_(s64) = G_CONSTANT i64 1
+ %zero:_(s64) = G_CONSTANT i64 0
+ %and:_(s64) = G_AND %x:_, %one:_
+ %res:_(s64) = G_SUB %zero:_, %and:_
+ $x0 = COPY %res:_(s64)
+ $x1 = COPY %and:_(s64)
...
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
new file mode 100644
index 0000000000000..69c550e05591b
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
@@ -0,0 +1,22 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -o - -mtriple=amdgcn -run-pass=amdgpu-prelegalizer-combiner %s | FileCheck %s
+---
+name: test_combine_neg_and_one_to_sext_inreg_v2i32
+body: |
+ bb.1:
+ liveins: $vgpr0_vgpr1
+ ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg_v2i32
+ ; CHECK: liveins: $vgpr0_vgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(<2 x s32>) = COPY $vgpr0_vgpr1
+ ; CHECK-NEXT: %res:_(<2 x s32>) = G_SEXT_INREG %x, 1
+ ; CHECK-NEXT: $vgpr0_vgpr1 = COPY %res(<2 x s32>)
+ %x:_(<2 x s32>) = COPY $vgpr0_vgpr1
+ %one:_(s32) = G_CONSTANT i32 1
+ %ones:_(<2 x s32>) = G_BUILD_VECTOR %one, %one
+ %zero:_(s32) = G_CONSTANT i32 0
+ %zeros:_(<2 x s32>) = G_BUILD_VECTOR %zero, %zero
+ %and:_(<2 x s32>) = G_AND %x:_, %ones:_
+ %res:_(<2 x s32>) = G_SUB %zeros:_, %and:_
+ $vgpr0_vgpr1 = COPY %res:_(<2 x s32>)
+...
>From f6aa40993751840ceb9fd838adfe67379c3f1126 Mon Sep 17 00:00:00 2001
From: Matthias Braun <matze at braunis.de>
Date: Mon, 31 Mar 2025 11:55:33 -0700
Subject: [PATCH 3/3] address review comment
---
.../combine-neg-and-one-to-sext-inreg.mir | 20 +++++++++++++++++
.../combine-neg-and-one-to-sext-inreg.mir | 22 -------------------
2 files changed, 20 insertions(+), 22 deletions(-)
delete mode 100644 llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
index b0d7de9b3f2d5..194a15f940da7 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
@@ -59,3 +59,23 @@ body: |
$x0 = COPY %res:_(s64)
$x1 = COPY %and:_(s64)
...
+---
+name: test_combine_neg_and_one_to_sext_inreg_v2i32
+body: |
+ bb.1:
+ liveins: $d0
+ ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg_v2i32
+ ; CHECK: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(<2 x s32>) = COPY $d0
+ ; CHECK-NEXT: %res:_(<2 x s32>) = G_SEXT_INREG %x, 1
+ ; CHECK-NEXT: $d0 = COPY %res(<2 x s32>)
+ %x:_(<2 x s32>) = COPY $d0
+ %one:_(s32) = G_CONSTANT i32 1
+ %ones:_(<2 x s32>) = G_BUILD_VECTOR %one, %one
+ %zero:_(s32) = G_CONSTANT i32 0
+ %zeros:_(<2 x s32>) = G_BUILD_VECTOR %zero, %zero
+ %and:_(<2 x s32>) = G_AND %x:_, %ones:_
+ %res:_(<2 x s32>) = G_SUB %zeros:_, %and:_
+ $d0 = COPY %res:_(<2 x s32>)
+...
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
deleted file mode 100644
index 69c550e05591b..0000000000000
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-neg-and-one-to-sext-inreg.mir
+++ /dev/null
@@ -1,22 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -o - -mtriple=amdgcn -run-pass=amdgpu-prelegalizer-combiner %s | FileCheck %s
----
-name: test_combine_neg_and_one_to_sext_inreg_v2i32
-body: |
- bb.1:
- liveins: $vgpr0_vgpr1
- ; CHECK-LABEL: name: test_combine_neg_and_one_to_sext_inreg_v2i32
- ; CHECK: liveins: $vgpr0_vgpr1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(<2 x s32>) = COPY $vgpr0_vgpr1
- ; CHECK-NEXT: %res:_(<2 x s32>) = G_SEXT_INREG %x, 1
- ; CHECK-NEXT: $vgpr0_vgpr1 = COPY %res(<2 x s32>)
- %x:_(<2 x s32>) = COPY $vgpr0_vgpr1
- %one:_(s32) = G_CONSTANT i32 1
- %ones:_(<2 x s32>) = G_BUILD_VECTOR %one, %one
- %zero:_(s32) = G_CONSTANT i32 0
- %zeros:_(<2 x s32>) = G_BUILD_VECTOR %zero, %zero
- %and:_(<2 x s32>) = G_AND %x:_, %ones:_
- %res:_(<2 x s32>) = G_SUB %zeros:_, %and:_
- $vgpr0_vgpr1 = COPY %res:_(<2 x s32>)
-...
More information about the llvm-commits
mailing list