Index: include/llvm/CodeGen/GlobalISel/LegalizerInfo.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -39,6 +39,7 @@ class MachineIRBuilder; class MachineRegisterInfo; class MCInstrInfo; +class TargetLowering; namespace LegalizeActions { enum LegalizeAction : std::uint8_t { @@ -205,6 +206,9 @@ /// True iff the specified type index is a vector whose element count is not a /// power of 2. LegalityPredicate numElementsNotPow2(unsigned TypeIdx); +/// True iff the pointer addressspacecast b/w Types at indices 0 and 1 are a +/// noop. +LegalityPredicate isNoopAddrSpaceCast(const TargetLowering *TLI); } // end namespace LegalityPredicates namespace LegalizeMutations { @@ -696,6 +700,13 @@ .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements()); } + /// Legal if the address space cast b/w the two pointers is a noop. + LegalizeRuleSet &legalIfNoopAddrSpaceCast(const TargetLowering *TLI) { + markAllTypeIdxsAsCovered(); + return actionIf(LegalizeAction::Legal, + LegalityPredicates::isNoopAddrSpaceCast(TLI)); + } + /// Fallback on the previous implementation. This should only be used while /// porting a rule. LegalizeRuleSet &fallback() { Index: lib/CodeGen/GlobalISel/LegalityPredicates.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalityPredicates.cpp +++ lib/CodeGen/GlobalISel/LegalityPredicates.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" +#include "llvm/CodeGen/TargetLowering.h" using namespace llvm; @@ -94,3 +95,14 @@ return QueryTy.isVector() && isPowerOf2_32(QueryTy.getNumElements()); }; } + +LegalityPredicate +LegalityPredicates::isNoopAddrSpaceCast(const TargetLowering *TLI) { + return [=](const LegalityQuery &Query) { + const LLT &Ty0 = Query.Types[0]; + const LLT &Ty1 = Query.Types[1]; + assert(Ty0.isPointer() && Ty1.isPointer()); + return TLI->isNoopAddrSpaceCast(Ty1.getAddressSpace(), + Ty0.getAddressSpace()); + }; +} Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -52,6 +52,9 @@ .clampScalar(0, s1, s64) .widenScalarToNextPow2(0, 8); + getActionDefinitionsBuilder(G_ADDRSPACE_CAST) + .legalIfNoopAddrSpaceCast(ST.getTargetLowering()); + getActionDefinitionsBuilder(G_PHI) .legalFor({p0, s16, s32, s64}) .clampScalar(0, s16, s64) Index: test/CodeGen/AArch64/GlobalISel/legalize-addrspacecast.mir =================================================================== --- /dev/null +++ test/CodeGen/AArch64/GlobalISel/legalize-addrspacecast.mir @@ -0,0 +1,21 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -o - -mtriple=aarch64-- -global-isel -run-pass=legalizer %s | FileCheck %s + +--- +name: test_addrspacecast +body: | + bb.1: + ; CHECK-LABEL: name: test_addrspacecast + ; CHECK: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF + ; CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[DEF]](s64) + ; CHECK: [[ADDRSPACE_CAST:%[0-9]+]]:_(p1) = G_ADDRSPACE_CAST [[INTTOPTR]](p0) + ; CHECK: [[ADDRSPACE_CAST1:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[ADDRSPACE_CAST]](p1) + ; CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[ADDRSPACE_CAST1]](p0) + ; CHECK: $x0 = COPY [[PTRTOINT]](s64) + %0:_(s64) = G_IMPLICIT_DEF + %1:_(p0) = G_INTTOPTR %0 + %2:_(p1) = G_ADDRSPACE_CAST %1 + %3:_(p0) = G_ADDRSPACE_CAST %2 + %4:_(s64) = G_PTRTOINT %3 + $x0 = COPY %4 +...