[llvm] [GlobalIsel] Combine cast of const integer. (PR #96139)
Thorsten Schütt via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 24 04:33:22 PDT 2024
https://github.com/tschuett updated https://github.com/llvm/llvm-project/pull/96139
>From ec811f8905062081ba8581f825d3ad9b85d34e83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Wed, 19 Jun 2024 16:12:50 +0200
Subject: [PATCH 1/3] [GlobalIsel] Combine cast of const integer.
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 4 +
.../include/llvm/Target/GlobalISel/Combine.td | 30 +++-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 54 ++++++
.../AArch64/GlobalISel/combine-cast-const.mir | 45 +++++
.../AArch64/GlobalISel/inline-memset.mir | 165 +++++++++---------
5 files changed, 218 insertions(+), 80 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 43659564d5ace..467754e3fb4f7 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -879,6 +879,10 @@ class CombinerHelper {
bool matchShlOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo);
+ bool matchZextInteger(const MachineInstr &MI, APInt &MatchInfo);
+ bool matchSextInteger(const MachineInstr &MI, APInt &MatchInfo);
+ bool matchTruncInteger(const MachineInstr &MI, APInt &MatchInfo);
+
private:
/// Checks for legality of an indexed variant of \p LdSt.
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index bd43b95899030..ed300d80f127f 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1758,6 +1758,34 @@ def freeze_combines: GICombineGroup<[
push_freeze_to_prevent_poison_from_propagating
]>;
+def ZextInteger: GICombineRule<
+ (defs root:$root, apint_matchinfo:$matchinfo),
+ (match (G_CONSTANT $int, $imm),
+ (G_ZEXT $root, $int):$mi,
+ [{ return Helper.matchZextInteger(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${mi}, ${matchinfo}); }])>;
+
+def SextInteger: GICombineRule<
+ (defs root:$root, apint_matchinfo:$matchinfo),
+ (match (G_CONSTANT $int, $imm),
+ (G_SEXT $root, $int):$mi,
+ [{ return Helper.matchSextInteger(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${mi}, ${matchinfo}); }])>;
+
+def TruncInteger: GICombineRule<
+ (defs root:$root, apint_matchinfo:$matchinfo),
+ (match (G_CONSTANT $int, $imm),
+ (G_TRUNC $root, $int):$mi,
+ [{ return Helper.matchTruncInteger(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${mi}, ${matchinfo}); }])>;
+
+def cast_const_combines: GICombineGroup<[
+ ZextInteger,
+ SextInteger,
+ TruncInteger,
+]>;
+
+
// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
undef_to_negative_one,
@@ -1820,7 +1848,7 @@ def prefer_sign_combines : GICombineGroup<[nneg_zext]>;
def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
vector_ops_combines, freeze_combines,
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
- combine_extracted_vector_load,
+ combine_extracted_vector_load, cast_const_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,
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 31030accd43f7..78998c90717d6 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7437,3 +7437,57 @@ bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
return false;
}
+
+bool CombinerHelper::matchZextInteger(const MachineInstr &MI,
+ APInt &MatchInfo) {
+ const GZext *Zext = cast<GZext>(&MI);
+
+ std::optional<APInt> Input = getIConstantVRegVal(Zext->getSrcReg(), MRI);
+ if (!Input)
+ return false;
+
+ LLT DstTy = MRI.getType(Zext->getReg(0));
+
+ if (!isConstantLegalOrBeforeLegalizer(DstTy))
+ return false;
+
+ MatchInfo = Input->zext(DstTy.getScalarSizeInBits());
+
+ return true;
+}
+
+bool CombinerHelper::matchSextInteger(const MachineInstr &MI,
+ APInt &MatchInfo) {
+ const GSext *Sext = cast<GSext>(&MI);
+
+ std::optional<APInt> Input = getIConstantVRegVal(Sext->getSrcReg(), MRI);
+ if (!Input)
+ return false;
+
+ LLT DstTy = MRI.getType(Sext->getReg(0));
+
+ if (!isConstantLegalOrBeforeLegalizer(DstTy))
+ return false;
+
+ MatchInfo = Input->sext(DstTy.getScalarSizeInBits());
+
+ return true;
+}
+
+bool CombinerHelper::matchTruncInteger(const MachineInstr &MI,
+ APInt &MatchInfo) {
+ const GTrunc *Trunc = cast<GTrunc>(&MI);
+
+ std::optional<APInt> Input = getIConstantVRegVal(Trunc->getSrcReg(), MRI);
+ if (!Input)
+ return false;
+
+ LLT DstTy = MRI.getType(Trunc->getReg(0));
+
+ if (!isConstantLegalOrBeforeLegalizer(DstTy))
+ return false;
+
+ MatchInfo = Input->trunc(DstTy.getScalarSizeInBits());
+
+ return true;
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
new file mode 100644
index 0000000000000..76d722cbf34c5
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
@@ -0,0 +1,45 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+
+---
+name: zext_const
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: zext_const
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %2:_(s32) = G_CONSTANT i32 5
+ %3:_(s64) = G_ZEXT %2
+ $x0 = COPY %3
+...
+---
+name: sext_const
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: sext_const
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -5
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %2:_(s32) = G_CONSTANT i32 -5
+ %3:_(s64) = G_SEXT %2
+ $x0 = COPY %3
+...
+---
+name: trunc_const
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: trunc_const
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 705032704
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %2:_(s64) = G_CONSTANT i64 5000000000
+ %3:_(s32) = G_TRUNC %2
+ $w0 = COPY %3
+
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/inline-memset.mir b/llvm/test/CodeGen/AArch64/GlobalISel/inline-memset.mir
index 00c7fc4cab3ab..9ed1e2d9eee3b 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/inline-memset.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/inline-memset.mir
@@ -64,13 +64,14 @@ body: |
; CHECK-LABEL: name: test_ms1
; CHECK: liveins: $w1, $w2, $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
- ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY2]](s32)
- ; CHECK: G_MEMSET [[COPY]](p0), [[TRUNC]](s8), [[ZEXT]](s64), 1 :: (store (s8) into %ir.dst)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[COPY2]](s32)
+ ; CHECK-NEXT: G_MEMSET [[COPY]](p0), [[TRUNC]](s8), [[ZEXT]](s64), 1 :: (store (s8) into %ir.dst)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s32) = COPY $w1
%2:_(s32) = COPY $w2
@@ -90,17 +91,18 @@ body: |
; CHECK-LABEL: name: test_ms2_const
; CHECK: liveins: $w1, $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC]](s8)
- ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72340172838076673
- ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]]
- ; CHECK: G_STORE [[MUL]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
- ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
- ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK: G_STORE [[MUL]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC]](s8)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72340172838076673
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]]
+ ; CHECK-NEXT: G_STORE [[MUL]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
+ ; CHECK-NEXT: G_STORE [[MUL]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s32) = COPY $w1
%3:_(s64) = G_CONSTANT i64 16
@@ -119,20 +121,21 @@ body: |
; CHECK-LABEL: name: test_zero_const
; CHECK: liveins: $w1, $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>) into %ir.dst, align 1)
- ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
- ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into %ir.dst + 16, align 1)
- ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
- ; CHECK: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD1]](p0) :: (store (<2 x s64>) into %ir.dst + 32, align 1)
- ; CHECK: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
- ; CHECK: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD2]](p0) :: (store (<2 x s64>) into %ir.dst + 48, align 1)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>) into %ir.dst, align 1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into %ir.dst + 16, align 1)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD1]](p0) :: (store (<2 x s64>) into %ir.dst + 32, align 1)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
+ ; CHECK-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD2]](p0) :: (store (<2 x s64>) into %ir.dst + 48, align 1)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s32) = G_CONSTANT i32 0
%3:_(s64) = G_CONSTANT i64 64
@@ -152,13 +155,14 @@ body: |
; CHECK-LABEL: name: test_ms3_const_both
; CHECK: liveins: $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4629771061636907072
- ; CHECK: G_STORE [[C]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
- ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
- ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK: G_STORE [[C]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4629771061636907072
+ ; CHECK-NEXT: G_STORE [[C]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
+ ; CHECK-NEXT: G_STORE [[C]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s8) = G_CONSTANT i8 64
%2:_(s64) = G_CONSTANT i64 16
@@ -176,24 +180,25 @@ body: |
; CHECK-LABEL: name: test_ms_vector
; CHECK: liveins: $w1, $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC]](s8)
- ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72340172838076673
- ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]]
- ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[MUL]](s64), [[MUL]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>) into %ir.dst, align 1)
- ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
- ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into %ir.dst + 16, align 1)
- ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
- ; CHECK: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD1]](p0) :: (store (<2 x s64>) into %ir.dst + 32, align 1)
- ; CHECK: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 44
- ; CHECK: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
- ; CHECK: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD2]](p0) :: (store (<2 x s64>) into %ir.dst + 44, align 1)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC]](s8)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72340172838076673
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]]
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[MUL]](s64), [[MUL]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>) into %ir.dst, align 1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD]](p0) :: (store (<2 x s64>) into %ir.dst + 16, align 1)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD1]](p0) :: (store (<2 x s64>) into %ir.dst + 32, align 1)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 44
+ ; CHECK-NEXT: [[PTR_ADD2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
+ ; CHECK-NEXT: G_STORE [[BUILD_VECTOR]](<2 x s64>), [[PTR_ADD2]](p0) :: (store (<2 x s64>) into %ir.dst + 44, align 1)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s32) = COPY $w1
%3:_(s64) = G_CONSTANT i64 60
@@ -212,17 +217,18 @@ body: |
; CHECK-LABEL: name: test_ms4_const_both_unaligned
; CHECK: liveins: $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4629771061636907072
- ; CHECK: G_STORE [[C]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
- ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
- ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK: G_STORE [[C]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[C]](s64)
- ; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
- ; CHECK: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
- ; CHECK: G_STORE [[TRUNC]](s16), [[PTR_ADD1]](p0) :: (store (s16) into %ir.dst + 16, align 1)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4629771061636907072
+ ; CHECK-NEXT: G_STORE [[C]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
+ ; CHECK-NEXT: G_STORE [[C]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s16) = G_CONSTANT i16 16448
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
+ ; CHECK-NEXT: G_STORE [[C2]](s16), [[PTR_ADD1]](p0) :: (store (s16) into %ir.dst + 16, align 1)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s8) = G_CONSTANT i8 64
%2:_(s64) = G_CONSTANT i64 18
@@ -239,17 +245,18 @@ body: |
liveins: $w1, $x0
; CHECK-LABEL: name: minsize
; CHECK: liveins: $w1, $x0
- ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC]](s8)
- ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72340172838076673
- ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]]
- ; CHECK: G_STORE [[MUL]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
- ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
- ; CHECK: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK: G_STORE [[MUL]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
- ; CHECK: RET_ReallyLR
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC]](s8)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72340172838076673
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[ZEXT]], [[C]]
+ ; CHECK-NEXT: G_STORE [[MUL]](s64), [[COPY]](p0) :: (store (s64) into %ir.dst, align 1)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
+ ; CHECK-NEXT: G_STORE [[MUL]](s64), [[PTR_ADD]](p0) :: (store (s64) into %ir.dst + 8, align 1)
+ ; CHECK-NEXT: RET_ReallyLR
%0:_(p0) = COPY $x0
%1:_(s32) = COPY $w1
%3:_(s64) = G_CONSTANT i64 16
>From eb412ee4bc30e6926068d4dffe8199fc8a9cf1c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Fri, 21 Jun 2024 11:08:38 +0200
Subject: [PATCH 2/3] address review comments
---
llvm/include/llvm/Target/GlobalISel/Combine.td | 2 +-
.../AArch64/GlobalISel/combine-cast-const.mir | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index ed300d80f127f..32599f164b988 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1782,7 +1782,7 @@ def TruncInteger: GICombineRule<
def cast_const_combines: GICombineGroup<[
ZextInteger,
SextInteger,
- TruncInteger,
+ TruncInteger
]>;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
index 76d722cbf34c5..4ab227145ea10 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
@@ -42,4 +42,21 @@ body: |
%2:_(s64) = G_CONSTANT i64 5000000000
%3:_(s32) = G_TRUNC %2
$w0 = COPY %3
+...
+---
+name: trunc_const_bv
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: trunc_const_bv
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 5000000000
+ ; CHECK-NEXT: %bv:_(<2 x s64>) = G_BUILD_VECTOR [[C]](s64), [[C]](s64)
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(<2 x s32>) = G_TRUNC %bv(<2 x s64>)
+ ; CHECK-NEXT: $x0 = COPY [[TRUNC]](<2 x s32>)
+ %2:_(s64) = G_CONSTANT i64 5000000000
+ %bv:_(<2 x s64>) = G_BUILD_VECTOR %2, %2
+ %3:_(<2 x s32>) = G_TRUNC %bv
+ $x0 = COPY %3
>From 3216e4514653cbe1b35ab681ae9bcec9cf3cfd4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Mon, 24 Jun 2024 13:32:15 +0200
Subject: [PATCH 3/3] add G_ANYEXT
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 1 +
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 8 +++++
.../include/llvm/Target/GlobalISel/Combine.td | 11 ++++++-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 24 ++++++++++++++
.../AArch64/GlobalISel/combine-cast-const.mir | 32 ++++++++++++++++++-
5 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 467754e3fb4f7..1986890b66918 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -882,6 +882,7 @@ class CombinerHelper {
bool matchZextInteger(const MachineInstr &MI, APInt &MatchInfo);
bool matchSextInteger(const MachineInstr &MI, APInt &MatchInfo);
bool matchTruncInteger(const MachineInstr &MI, APInt &MatchInfo);
+ bool matchAnyextInteger(const MachineInstr &MI, APInt &MatchInfo);
private:
/// Checks for legality of an indexed variant of \p LdSt.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 995031f7c00be..c47973cb4d752 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -858,6 +858,14 @@ class GTrunc : public GCastOp {
};
};
+/// Represents an anyext.
+class GAnyExt : public GCastOp {
+public:
+ static bool classof(const MachineInstr *MI) {
+ return MI->getOpcode() == TargetOpcode::G_ANYEXT;
+ };
+};
+
/// Represents a vscale.
class GVScale : public GenericMachineInstr {
public:
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 32599f164b988..8129a8ceb50c2 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1779,10 +1779,19 @@ def TruncInteger: GICombineRule<
[{ return Helper.matchTruncInteger(*${mi}, ${matchinfo}); }]),
(apply [{ Helper.replaceInstWithConstant(*${mi}, ${matchinfo}); }])>;
+def AnyExtInteger: GICombineRule<
+ (defs root:$root, apint_matchinfo:$matchinfo),
+ (match (G_CONSTANT $int, $imm),
+ (G_ANYEXT $root, $int):$mi,
+ [{ return Helper.matchAnyextInteger(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${mi}, ${matchinfo}); }])>;
+
+
def cast_const_combines: GICombineGroup<[
ZextInteger,
SextInteger,
- TruncInteger
+ TruncInteger,
+ AnyExtInteger
]>;
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 78998c90717d6..65c0cb884380e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7491,3 +7491,27 @@ bool CombinerHelper::matchTruncInteger(const MachineInstr &MI,
return true;
}
+
+bool CombinerHelper::matchAnyextInteger(const MachineInstr &MI,
+ APInt &MatchInfo) {
+ const GAnyExt *Anyext = cast<GAnyExt>(&MI);
+
+ std::optional<APInt> Input = getIConstantVRegVal(Anyext->getSrcReg(), MRI);
+ if (!Input)
+ return false;
+
+ LLT DstTy = MRI.getType(Anyext->getReg(0));
+ LLT SrcTy = MRI.getType(Anyext->getSrcReg());
+ const auto &TLI = getTargetLowering();
+
+ if (!isConstantLegalOrBeforeLegalizer(DstTy))
+ return false;
+
+ // Some targets like RISCV prefer to sign extend some types.
+ if (TLI.isSExtCheaperThanZExt(getMVTForLLT(SrcTy), getMVTForLLT(DstTy)))
+ MatchInfo = Input->sext(DstTy.getScalarSizeInBits());
+ else
+ MatchInfo = Input->zext(DstTy.getScalarSizeInBits());
+
+ return true;
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
index 4ab227145ea10..47932fcdd00aa 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-cast-const.mir
@@ -59,4 +59,34 @@ body: |
%bv:_(<2 x s64>) = G_BUILD_VECTOR %2, %2
%3:_(<2 x s32>) = G_TRUNC %bv
$x0 = COPY %3
-
+...
+---
+name: anyext_const
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: anyext_const
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 500
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %2:_(s32) = G_CONSTANT i32 500
+ %3:_(s64) = G_ANYEXT %2
+ $x0 = COPY %3
+...
+---
+name: mul_abs_const
+body: |
+ bb.0:
+ liveins: $q0, $q1
+ ; CHECK-LABEL: name: mul_abs_const
+ ; CHECK: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %x:_(s32) = COPY $w0
+ %zero:_(s32) = G_CONSTANT i32 0
+ %mul:_(s32) = G_MUL %x, %zero
+ %3:_(s64) = G_ANYEXT %mul
+ %abs:_(s64) = G_ABS %3
+ $x0 = COPY %3
More information about the llvm-commits
mailing list