[llvm] [GlobalIsel] Combine G_PTR_ADD. (PR #95647)
Thorsten Schütt via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 15 01:25:47 PDT 2024
https://github.com/tschuett created https://github.com/llvm/llvm-project/pull/95647
Hints from https://reviews.llvm.org/D109528
>From 47ddeed49fc85e41f9363aef7aadf73c289ca465 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= <schuett at gmail.com>
Date: Thu, 6 Jun 2024 15:09:55 +0200
Subject: [PATCH] [GlobalIsel] Combine G_PTR_ADD.
Hints from https://reviews.llvm.org/D109528
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 10 +
.../include/llvm/Target/GlobalISel/Combine.td | 71 ++++-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 209 ++++++++++++++
.../GlobalISel/CombinerHelperVectorOps.cpp | 49 ++++
.../AArch64/GlobalISel/combine-ptradd.mir | 273 ++++++++++++++++++
.../AArch64/GlobalISel/combine-vscale.mir | 48 +++
6 files changed, 659 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-ptradd.mir
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 43659564d5ace..2bce6ba470f67 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -879,6 +879,16 @@ class CombinerHelper {
bool matchShlOfVScale(const MachineOperand &MO, BuildFnTy &MatchInfo);
+ bool matchPtrAddWithSub(const MachineOperand &MO, BuildFnTy &MatchInfo);
+ bool matchPtrAddWithAdd(const MachineOperand &MO, BuildFnTy &MatchInfo);
+ bool matchPtrAddsFoldConstants(MachineOperand &MO, BuildFnTy &MatchInfo);
+ bool matchPtrAddWFoldDistributedConstants(const MachineOperand &MO,
+ BuildFnTy &MatchInfo);
+ bool matchPtrAddMoveInner(MachineOperand &MO, BuildFnTy &MatchInfo);
+
+ bool matchPtrAddWithAddVScale(const MachineOperand &MO, BuildFnTy &MatchInfo);
+ bool matchPtrAddWithSubVScale(const MachineOperand &MO, BuildFnTy &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..a35200de105b3 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1675,6 +1675,75 @@ shl_of_vscale,
sub_of_vscale,
]>;
+def PtrAddWithSub : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_CONSTANT $right, $imm),
+ (G_SUB $offset, $left, $right),
+ (G_PTR_ADD $root, $base, $offset),
+ [{ return Helper.matchPtrAddWithSub(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+def PtrAddWithAdd : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_CONSTANT $right, $imm),
+ (G_ADD $offset, $left, $right),
+ (G_PTR_ADD $root, $base, $offset),
+ [{ return Helper.matchPtrAddWithAdd(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+def PtrAdd2DistributedConstOffsets : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_CONSTANT $const2, $imm2),
+ (G_CONSTANT $const1, $imm1),
+ (G_PTR_ADD $pointer1, $base, $const2),
+ (G_PTR_ADD $pointer, $pointer1, $nonconst),
+ (G_PTR_ADD $root, $pointer, $const1),
+ [{ return Helper.matchPtrAddWFoldDistributedConstants(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+def PtrAdd2ConstOffsets : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_CONSTANT $const2, $imm2),
+ (G_CONSTANT $const1, $imm1),
+ (G_PTR_ADD $pointer, $base, $const2),
+ (G_PTR_ADD $root, $pointer, $const1),
+ [{ return Helper.matchPtrAddsFoldConstants(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+def PtrAddMoveInner : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_CONSTANT $const, $imm),
+ (G_PTR_ADD $pointer, $base, $const),
+ (G_PTR_ADD $root, $pointer, $nonconst),
+ [{ return Helper.matchPtrAddMoveInner(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+def PtrAddWithAddVScale : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_VSCALE $right, $imm),
+ (G_ADD $offset, $left, $right),
+ (G_PTR_ADD $root, $base, $offset),
+ [{ return Helper.matchPtrAddWithAddVScale(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+def PtrSubWithSubVScale : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (G_VSCALE $right, $imm),
+ (G_SUB $offset, $left, $right),
+ (G_PTR_ADD $root, $base, $offset),
+ [{ return Helper.matchPtrAddWithSubVScale(${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
+
+
+def ptradd_combines: GICombineGroup<[
+PtrAddWithSub,
+PtrAddWithAdd,
+PtrAdd2ConstOffsets,
+PtrAdd2DistributedConstOffsets,
+PtrAddMoveInner,
+PtrAddWithAddVScale,
+PtrSubWithSubVScale
+]>;
// fold ((0-A) + B) -> B-A
def ZeroMinusAPlusB : GICombineRule<
@@ -1818,7 +1887,7 @@ def constant_fold_binops : GICombineGroup<[constant_fold_binop,
def prefer_sign_combines : GICombineGroup<[nneg_zext]>;
def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
- vector_ops_combines, freeze_combines,
+ vector_ops_combines, freeze_combines, ptradd_combines,
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
combine_extracted_vector_load,
undef_combines, identity_combines, phi_combines,
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 02d85958fc7be..55588e41bdb14 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7444,3 +7444,212 @@ bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
return false;
}
+
+bool CombinerHelper::matchPtrAddWithSub(const MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GSub *Sub = cast<GSub>(MRI.getVRegDef(Inner->getOffsetReg()));
+
+ // sub(x, c) -> add(x, -c)
+
+ // one-use check
+ if (!MRI.hasOneNonDBGUse(Sub->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeImm = getIConstantVRegVal(Sub->getRHSReg(), MRI);
+ if (!MaybeImm)
+ return false;
+
+ LLT ConstTy = MRI.getType(Inner->getOffsetReg());
+
+ if (!isConstantLegalOrBeforeLegalizer(ConstTy))
+ return false;
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Base = B.buildConstant(ConstTy, -(*MaybeImm));
+ auto PtrAdd = B.buildPtrAdd(DstTy, Inner->getBaseReg(), Sub->getLHSReg());
+ B.buildPtrAdd(Dst, PtrAdd, Base);
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchPtrAddWithAdd(const MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GAdd *Add = cast<GAdd>(MRI.getVRegDef(Inner->getOffsetReg()));
+
+ // one-use check
+ if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+ return false;
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto PtrAdd = B.buildPtrAdd(DstTy, Inner->getBaseReg(), Add->getLHSReg());
+ B.buildPtrAdd(Dst, PtrAdd, Add->getRHSReg());
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchPtrAddsFoldConstants(MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GPtrAdd *Second = cast<GPtrAdd>(MRI.getVRegDef(Inner->getBaseReg()));
+
+ // one-use check
+ if (!MRI.hasOneNonDBGUse(Second->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeImm1 =
+ getIConstantVRegVal(Inner->getOffsetReg(), MRI);
+ if (!MaybeImm1)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeImm2 =
+ getIConstantVRegVal(Second->getOffsetReg(), MRI);
+ if (!MaybeImm2)
+ return false;
+
+ // Check if we can combine the two offsets into a legal addressing mode.
+ // To do so, we first need to find a load/store user of the pointer to get
+ // the access type. We cannot put the memory access into the MIR pattern.
+ Type *AccessTy = nullptr;
+ auto &MF = *MO.getParent()->getMF();
+ for (auto &UseMI :
+ MRI.use_nodbg_instructions(Inner->getOperand(0).getReg())) {
+ if (auto *LdSt = dyn_cast<GLoadStore>(&UseMI)) {
+ AccessTy = getTypeForLLT(LdSt->getMMO().getMemoryType(),
+ MF.getFunction().getContext());
+ break;
+ }
+ }
+
+ // Did we found a memory access?
+ if (!AccessTy)
+ return false;
+
+ TargetLoweringBase::AddrMode AM;
+ AM.HasBaseReg = true;
+ AM.BaseOffs = (*MaybeImm1 + *MaybeImm2).getSExtValue();
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+
+ unsigned AS = DstTy.getAddressSpace();
+
+ const auto &TLI = getTargetLowering();
+
+ // Can we combine the two offsets?
+ if (!TLI.isLegalAddressingMode(MF.getDataLayout(), AM, AccessTy, AS))
+ return false;
+
+ LLT ConstTy = MRI.getType(Second->getOffsetReg());
+
+ if (!isConstantLegalOrBeforeLegalizer(ConstTy))
+ return false;
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Offset = B.buildConstant(ConstTy, AM.BaseOffs);
+ B.buildPtrAdd(Dst, Second->getBaseReg(), Offset);
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchPtrAddWFoldDistributedConstants(
+ const MachineOperand &MO, BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GPtrAdd *Second = cast<GPtrAdd>(MRI.getVRegDef(Inner->getBaseReg()));
+ GPtrAdd *Third = cast<GPtrAdd>(MRI.getVRegDef(Second->getBaseReg()));
+
+ if (!MRI.hasOneNonDBGUse(Second->getReg(0)) ||
+ !MRI.hasOneNonDBGUse(Third->getReg(0)))
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeImm1 =
+ getIConstantVRegVal(Inner->getOffsetReg(), MRI);
+ if (!MaybeImm1)
+ return false;
+
+ // Cannot fail due to pattern.
+ std::optional<APInt> MaybeImm2 =
+ getIConstantVRegVal(Third->getOffsetReg(), MRI);
+ if (!MaybeImm2)
+ return false;
+
+ // Check if we can combine the two offsets into a legal addressing mode.
+ // To do so, we first need to find a load/store user of the pointer to get
+ // the access type. We cannot put the memory access into the MIR pattern.
+ Type *AccessTy = nullptr;
+ auto &MF = *MO.getParent()->getMF();
+ for (auto &UseMI :
+ MRI.use_nodbg_instructions(Inner->getOperand(0).getReg())) {
+ if (auto *LdSt = dyn_cast<GLoadStore>(&UseMI)) {
+ AccessTy = getTypeForLLT(LdSt->getMMO().getMemoryType(),
+ MF.getFunction().getContext());
+ break;
+ }
+ }
+
+ // Did we found a memory access?
+ if (!AccessTy)
+ return false;
+
+ TargetLoweringBase::AddrMode AM;
+ AM.HasBaseReg = true;
+ AM.BaseOffs = (*MaybeImm1 + *MaybeImm2).getSExtValue();
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+ unsigned AS = DstTy.getAddressSpace();
+
+ const auto &TLI = getTargetLowering();
+
+ // Can we combine the two offsets?
+ if (!TLI.isLegalAddressingMode(MF.getDataLayout(), AM, AccessTy, AS))
+ return false;
+
+ LLT ConstTy = MRI.getType(Third->getOffsetReg());
+
+ if (!isConstantLegalOrBeforeLegalizer(ConstTy))
+ return false;
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto Offset = B.buildConstant(ConstTy, AM.BaseOffs);
+ auto PtrAdd =
+ B.buildPtrAdd(DstTy, Third->getBaseReg(), Second->getOffsetReg());
+ B.buildPtrAdd(Dst, PtrAdd, Offset);
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchPtrAddMoveInner(MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GPtrAdd *Second = cast<GPtrAdd>(MRI.getVRegDef(Inner->getBaseReg()));
+
+ if (!MRI.hasOneNonDBGUse(Second->getReg(0)))
+ return false;
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto PtrAdd =
+ B.buildPtrAdd(DstTy, Second->getBaseReg(), Inner->getOffsetReg());
+ B.buildPtrAdd(Dst, PtrAdd, Second->getOffsetReg());
+ };
+
+ return true;
+}
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
index 66b1c5f8ca82c..4c962342e631a 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
@@ -484,3 +484,52 @@ bool CombinerHelper::matchShlOfVScale(const MachineOperand &MO,
return true;
}
+
+bool CombinerHelper::matchPtrAddWithAddVScale(const MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GAdd *Add = cast<GAdd>(MRI.getVRegDef(Inner->getOffsetReg()));
+ GVScale *VScale = cast<GVScale>(MRI.getVRegDef(Add->getRHSReg()));
+
+ // one-use check
+ if (!MRI.hasOneNonDBGUse(Add->getReg(0)) ||
+ !MRI.hasOneNonDBGUse(VScale->getReg(0)))
+ return false;
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto PtrAdd = B.buildPtrAdd(DstTy, Inner->getBaseReg(), Add->getLHSReg());
+ B.buildPtrAdd(Dst, PtrAdd, Add->getRHSReg());
+ };
+
+ return true;
+}
+
+bool CombinerHelper::matchPtrAddWithSubVScale(const MachineOperand &MO,
+ BuildFnTy &MatchInfo) {
+ GPtrAdd *Inner = cast<GPtrAdd>(MRI.getVRegDef(MO.getReg()));
+ GSub *Sub = cast<GSub>(MRI.getVRegDef(Inner->getOffsetReg()));
+ GVScale *VScale = cast<GVScale>(MRI.getVRegDef(Sub->getRHSReg()));
+
+ // one-use check
+ if (!MRI.hasOneNonDBGUse(Sub->getReg(0)) ||
+ !MRI.hasOneNonDBGUse(VScale->getReg(0)))
+ return false;
+
+ Register Dst = MO.getReg();
+ LLT DstTy = MRI.getType(Dst);
+ LLT VScaleTy = MRI.getType(Inner->getOffsetReg());
+
+ if (!isLegalOrBeforeLegalizer({TargetOpcode::G_VSCALE, VScaleTy}))
+ return false;
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto VScaleMI = B.buildVScale(VScaleTy, -VScale->getSrc());
+ auto PtrAdd = B.buildPtrAdd(DstTy, Inner->getBaseReg(), Sub->getLHSReg());
+ B.buildPtrAdd(Dst, PtrAdd, VScaleMI);
+ };
+
+ return true;
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-ptradd.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-ptradd.mir
new file mode 100644
index 0000000000000..31e975f66d07b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-ptradd.mir
@@ -0,0 +1,273 @@
+# 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: ptradd_with_sub
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: ptradd_with_sub
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1600
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[COPY1]](s64)
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTR_ADD]], [[C]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[PTR_ADD1]](p0)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x0
+ %2:_(s64) = G_CONSTANT i64 1600
+ %10:_(s64) = G_SUB %1, %2(s64)
+ %11:_(p0) = G_PTR_ADD %0, %10(s64)
+ $x0 = COPY %11(p0)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: ptradd_with_sub_multiple_use
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: ptradd_with_sub_multiple_use
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1600
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s64) = G_SUB [[COPY1]], [[C]]
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[SUB]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0)
+ ; CHECK-NEXT: $x1 = COPY [[SUB]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x0
+ %2:_(s64) = G_CONSTANT i64 1600
+ %10:_(s64) = G_SUB %1, %2(s64)
+ %11:_(p0) = G_PTR_ADD %0, %10(s64)
+ $x0 = COPY %11(p0)
+ $x1 = COPY %10(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: ptradd_with_add
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: ptradd_with_add
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1600
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[COPY1]](s64)
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[PTR_ADD]], [[C]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[PTR_ADD1]](p0)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s64) = G_CONSTANT i64 1600
+ %10:_(s64) = G_ADD %1, %2(s64)
+ %11:_(p0) = G_PTR_ADD %0, %10(s64)
+ $x0 = COPY %11(p0)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: load_with_two_constants
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x0' }
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: load_with_two_constants
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 17
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD]](p0) :: (load (s64))
+ ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x0
+ %3:_(s64) = G_CONSTANT i64 16
+ %4:_(s64) = G_CONSTANT i64 1
+ %13:_(p0) = G_PTR_ADD %0, %3(s64)
+ %12:_(p0) = nsw G_PTR_ADD %13, %4(s64)
+ %14:_(s64) = G_LOAD %12(p0) :: (load (s64))
+ $x0 = COPY %14(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: load_with_two_constants_large
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: load_with_two_constants_large
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 3000
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD]](p0) :: (load (s64))
+ ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %3:_(s64) = G_CONSTANT i64 1000
+ %4:_(s64) = G_CONSTANT i64 2000
+ %13:_(p0) = G_PTR_ADD %0, %3(s64)
+ %12:_(p0) = nsw G_PTR_ADD %13, %4(s64)
+ %14:_(s64) = G_LOAD %12(p0) :: (load (s64))
+ $x0 = COPY %14(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: load_with_two_distributed_constants
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: load_with_two_distributed_constants
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[COPY1]](s64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 17
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[PTR_ADD]], [[C]](s64)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD1]](p0) :: (load (s64))
+ ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %3:_(s64) = G_CONSTANT i64 16
+ %4:_(s64) = G_CONSTANT i64 1
+ %14:_(p0) = G_PTR_ADD %0, %3(s64)
+ %13:_(p0) = G_PTR_ADD %14, %1(s64)
+ %12:_(p0) = nsw G_PTR_ADD %13, %4(s64)
+ %15:_(s64) = G_LOAD %12(p0) :: (load (s64))
+ $x0 = COPY %15(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: move_inner
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: move_inner
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[COPY1]](s64)
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[PTR_ADD]], [[C]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[PTR_ADD1]](p0)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %3:_(s64) = G_CONSTANT i64 16
+ %13:_(p0) = G_PTR_ADD %0, %3(s64)
+ %12:_(p0) = nsw G_PTR_ADD %13, %1(s64)
+ $x0 = COPY %12(p0)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: move_inner_rotate
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: move_inner_rotate
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
+ ; CHECK-NEXT: [[CONSTANT_FOLD_BARRIER:%[0-9]+]]:_(s64) = G_CONSTANT_FOLD_BARRIER [[C1]]
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[CONSTANT_FOLD_BARRIER]](s64)
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[PTR_ADD]], [[C]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[PTR_ADD1]](p0)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %3:_(s64) = G_CONSTANT i64 16
+ %4:_(s64) = G_CONSTANT i64 32
+ %5:_(s64) = G_CONSTANT_FOLD_BARRIER %4
+ %13:_(p0) = G_PTR_ADD %0, %3(s64)
+ %12:_(p0) = nsw G_PTR_ADD %13, %5(s64)
+ $x0 = COPY %12(p0)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: load_with_three_constants
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: load_with_three_constants
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 60
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD]](p0) :: (load (s64))
+ ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s64) = G_CONSTANT i64 10
+ %3:_(s64) = G_CONSTANT i64 20
+ %4:_(s64) = G_CONSTANT i64 30
+ %12:_(p0) = G_PTR_ADD %0, %2(s64)
+ %13:_(p0) = G_PTR_ADD %12, %3(s64)
+ %14:_(p0) = nsw G_PTR_ADD %13, %4(s64)
+ %15:_(s64) = G_LOAD %14(p0) :: (load (s64))
+ $x0 = COPY %15(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: load_with_two_constants_and_sub
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: load_with_two_constants_and_sub
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[COPY1]](s64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 20
+ ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:_(p0) = nsw G_PTR_ADD [[PTR_ADD]], [[C]](s64)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[PTR_ADD1]](p0) :: (load (s64))
+ ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(p0) = COPY $x0
+ %1:_(s64) = COPY $x1
+ %2:_(s64) = G_CONSTANT i64 10
+ %4:_(s64) = G_CONSTANT i64 30
+ %12:_(s64) = G_SUB %1, %2(s64)
+ %13:_(p0) = G_PTR_ADD %0, %12(s64)
+ %14:_(p0) = nsw G_PTR_ADD %13, %4(s64)
+ %15:_(s64) = G_LOAD %14(p0) :: (load (s64))
+ $x0 = COPY %15(s64)
+ RET_ReallyLR implicit $x0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-vscale.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-vscale.mir
index 9b7a44954afdb..6ae93d6dbea5e 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-vscale.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-vscale.mir
@@ -111,3 +111,51 @@ body: |
%shl:_(s64) = nuw G_SHL %lhs(s64), %rhs(s64)
$x0 = COPY %shl(s64)
RET_ReallyLR implicit $x0
+...
+---
+name: ptradd_add_vscale
+body: |
+ bb.1:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: ptradd_add_vscale
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %p:_(p0) = COPY $x0
+ ; CHECK-NEXT: %opaque:_(s64) = COPY $x0
+ ; CHECK-NEXT: %vs:_(s64) = G_VSCALE i64 11
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD %p, %opaque(s64)
+ ; CHECK-NEXT: %ptradd:_(p0) = G_PTR_ADD [[PTR_ADD]], %vs(s64)
+ ; CHECK-NEXT: $x0 = COPY %ptradd(p0)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %p:_(p0) = COPY $x0
+ %opaque:_(s64) = COPY $x0
+ %cons:_(s64) = G_CONSTANT i64 2
+ %vs:_(s64) = G_VSCALE i64 11
+ %rhs:_(s64) = G_ADD %opaque(s64), %vs(s64)
+ %ptradd:_(p0) = nuw G_PTR_ADD %p(p0), %rhs(s64)
+ $x0 = COPY %ptradd(p0)
+ RET_ReallyLR implicit $x0
+...
+---
+name: ptradd_sub_vscale
+body: |
+ bb.1:
+ liveins: $x0, $x1
+ ; CHECK-LABEL: name: ptradd_sub_vscale
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %p:_(p0) = COPY $x0
+ ; CHECK-NEXT: %opaque:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[VSCALE:%[0-9]+]]:_(s64) = G_VSCALE i64 -11
+ ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD %p, %opaque(s64)
+ ; CHECK-NEXT: %ptradd:_(p0) = G_PTR_ADD [[PTR_ADD]], [[VSCALE]](s64)
+ ; CHECK-NEXT: $x0 = COPY %ptradd(p0)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %p:_(p0) = COPY $x0
+ %opaque:_(s64) = COPY $x0
+ %cons:_(s64) = G_CONSTANT i64 2
+ %vs:_(s64) = G_VSCALE i64 11
+ %rhs:_(s64) = G_SUB %opaque(s64), %vs(s64)
+ %ptradd:_(p0) = nuw G_PTR_ADD %p(p0), %rhs(s64)
+ $x0 = COPY %ptradd(p0)
+ RET_ReallyLR implicit $x0
More information about the llvm-commits
mailing list