llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-globalisel Author: Amara Emerson (aemerson) <details> <summary>Changes</summary> --- Full diff: https://github.com/llvm/llvm-project/pull/121171.diff 5 Files Affected: - (modified) llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h (+4) - (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+15) - (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp (+25) - (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h (+1) - (modified) llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir (+23-1) ``````````diff diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h index 2384b22c052662..90276c2d6fdfd1 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -297,6 +297,10 @@ class LegalizerHelper { MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment, MachinePointerInfo &PtrInfo); + /// Create a store of \p Val to a stack temporary and return a load of the + /// same value as type \p DestVT. + MachineInstrBuilder createStackStoreLoad(Register Val, LLT DstTy); + /// Get a pointer to vector element \p Index located in memory for a vector of /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out /// of bounds the returned pointer is unspecified, but will be within the diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index a931123638ffb9..6e87acef6ca7d3 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -22,6 +22,7 @@ #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Utils.h" +#include "llvm/CodeGen/LowLevelTypeUtils.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -4663,6 +4664,20 @@ LegalizerHelper::createStackTemporary(TypeSize Bytes, Align Alignment, return MIRBuilder.buildFrameIndex(FramePtrTy, FrameIdx); } +MachineInstrBuilder LegalizerHelper::createStackStoreLoad(Register Val, + LLT DstTy) { + LLT SrcTy = MRI.getType(Val); + Align StackTypeAlign = getStackTemporaryAlignment(SrcTy); + MachinePointerInfo PtrInfo; + auto StackTemp = + createStackTemporary(SrcTy.getSizeInBytes(), StackTypeAlign, PtrInfo); + + MIRBuilder.buildStore(Val, StackTemp, PtrInfo, StackTypeAlign); + return MIRBuilder.buildLoad( + DstTy, StackTemp, PtrInfo, + std::min(StackTypeAlign, getStackTemporaryAlignment(DstTy))); +} + static Register clampVectorIndex(MachineIRBuilder &B, Register IdxReg, LLT VecTy) { LLT IdxTy = B.getMRI()->getType(IdxReg); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index 2c35482b7c9e5f..16b0587e799c7b 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -862,6 +862,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) .legalForCartesianProduct({s32, v2s16, v4s8}) .legalForCartesianProduct({s64, v8s8, v4s16, v2s32}) .legalForCartesianProduct({s128, v16s8, v8s16, v4s32, v2s64, v2p0}) + .customIf([=](const LegalityQuery &Query) { + // Handle casts from i1 vectors to scalars. + LLT DstTy = Query.Types[0]; + LLT SrcTy = Query.Types[1]; + return DstTy.isScalar() && SrcTy.isVector() && + SrcTy.getScalarSizeInBits() == 1; + }) .lowerIf([=](const LegalityQuery &Query) { return Query.Types[0].isVector() != Query.Types[1].isVector(); }) @@ -1405,11 +1412,29 @@ bool AArch64LegalizerInfo::legalizeCustom( return Helper.lowerAbsToCNeg(MI); case TargetOpcode::G_ICMP: return legalizeICMP(MI, MRI, MIRBuilder); + case TargetOpcode::G_BITCAST: + return legalizeBitcast(MI, Helper); } llvm_unreachable("expected switch to return"); } +bool AArch64LegalizerInfo::legalizeBitcast(MachineInstr &MI, + LegalizerHelper &Helper) const { + assert(MI.getOpcode() == TargetOpcode::G_BITCAST && "Unexpected opcode"); + auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs(); + // We're trying to handle casts from i1 vectors to scalars but reloading from + // stack. + if (!DstTy.isScalar() || !SrcTy.isVector() || + SrcTy.getElementType() != LLT::scalar(1)) + return false; + + auto Load = Helper.createStackStoreLoad(SrcReg, DstTy); + Helper.MIRBuilder.buildCopy(DstReg, Load.getReg(0)); + MI.eraseFromParent(); + return true; +} + bool AArch64LegalizerInfo::legalizeFunnelShift(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder, diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h index 00d85a36e4b2ca..bcb294326fa92a 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h @@ -66,6 +66,7 @@ class AArch64LegalizerInfo : public LegalizerInfo { LegalizerHelper &Helper) const; bool legalizeDynStackAlloc(MachineInstr &MI, LegalizerHelper &Helper) const; bool legalizePrefetch(MachineInstr &MI, LegalizerHelper &Helper) const; + bool legalizeBitcast(MachineInstr &MI, LegalizerHelper &Helper) const; const AArch64Subtarget *ST; }; } // End llvm namespace. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir index e3a633c9e035d0..be5699dab5b6de 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 -# RUN: llc -mtriple=aarch64 -run-pass=legalizer -global-isel-abort=1 %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64 -run-pass=legalizer -global-isel-abort=2 %s -o - | FileCheck %s --- name: scalar_to_oversize_vector tracksRegLiveness: true @@ -48,3 +48,25 @@ body: | G_BR %bb.2 ... +# This test currently is expected to fall back after reaching truncstore of <8 x s8> as <8 x s1>. +--- +name: boolean_vector_to_scalar +tracksRegLiveness: true +body: | + bb.1: + ; CHECK-LABEL: name: boolean_vector_to_scalar + ; CHECK: %vec:_(<8 x s1>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0 + ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<8 x s8>) = G_ANYEXT %vec(<8 x s1>) + ; CHECK-NEXT: G_STORE [[ANYEXT]](<8 x s8>), [[FRAME_INDEX]](p0) :: (store (<8 x s1>) into %stack.0) + ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s8) from %stack.0) + ; CHECK-NEXT: %bc:_(s8) = COPY [[LOAD]](s8) + ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %bc(s8) + ; CHECK-NEXT: $w0 = COPY %ext(s32) + ; CHECK-NEXT: RET_ReallyLR implicit $w0 + %vec:_(<8 x s1>) = G_IMPLICIT_DEF + %bc:_(s8) = G_BITCAST %vec(<8 x s1>) + %ext:_(s32) = G_ANYEXT %bc(s8) + $w0 = COPY %ext(s32) + RET_ReallyLR implicit $w0 +... `````````` </details> https://github.com/llvm/llvm-project/pull/121171 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits