From 2e773626266420d0fa515606a3aa19b58be18ec9 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 14 Feb 2020 11:51:57 -0500 Subject: [PATCH] GlobalISel: Fix lower bswap for vectors This would hit an assertion from trying to use the wrong bitwidth for the constants. --- .../CodeGen/GlobalISel/MachineIRBuilder.h | 5 +++ .../CodeGen/GlobalISel/LegalizerHelper.cpp | 2 +- .../GlobalISel/LegalizerHelperTest.cpp | 43 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index da7258b60f2f5..59c2aa898d4fd 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -1446,6 +1446,11 @@ class MachineIRBuilder { return buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {Dst}, {Src0}); } + /// Build and insert \p Dst = G_BSWAP \p Src0 + MachineInstrBuilder buildBSwap(const DstOp &Dst, const SrcOp &Src0) { + return buildInstr(TargetOpcode::G_BSWAP, {Dst}, {Src0}); + } + /// Build and insert \p Res = G_FADD \p Op0, \p Op1 MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 50317bfe9177b..d7cbdbc3c9046 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -4956,7 +4956,7 @@ LegalizerHelper::lowerBswap(MachineInstr &MI) { Register Dst = MI.getOperand(0).getReg(); Register Src = MI.getOperand(1).getReg(); const LLT Ty = MRI.getType(Src); - unsigned SizeInBytes = Ty.getSizeInBytes(); + unsigned SizeInBytes = (Ty.getScalarSizeInBits() + 7) / 8; unsigned BaseShiftAmt = (SizeInBytes - 1) * 8; // Swap most and least significant byte, set remaining bytes in Res to zero. diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp index e8ecdb5342d86..9407a9437bcc9 100644 --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp @@ -2473,4 +2473,47 @@ TEST_F(GISelMITest, LowerFFloor) { // Check EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; } + +// Test lowering of G_BSWAP +TEST_F(GISelMITest, LowerBSWAP) { + setUp(); + if (!TM) + return; + + DefineLegalizerInfo(A, {}); + + // Make sure vector lowering doesn't assert. + auto Cast = B.buildBitcast(LLT::vector(2, 32), Copies[0]); + auto BSwap = B.buildBSwap(LLT::vector(2, 32), Cast); + AInfo Info(MF->getSubtarget()); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer, B); + // Perform Legalization + EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, + Helper.lower(*BSwap, 0, LLT())); + + auto CheckStr = R"( + CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY + CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]] + CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 24 + CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32) + CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]] + CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]] + CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_ + CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 65280 + CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32) + CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 + CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32) + CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_ + CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]] + CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_ + CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]] + CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_ + CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_ + )"; + + // Check + EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; +} + } // namespace