Index: include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h =================================================================== --- include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -489,6 +489,11 @@ return buildInstr(TargetOpcode::G_PTRTOINT, {Dst}, {Src}); } + /// Build and insert a G_INTTOPTR instruction. + MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src) { + return buildInstr(TargetOpcode::G_INTTOPTR, {Dst}, {Src}); + } + /// Build and insert \p Dst = G_BITCAST \p Src MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src) { return buildInstr(TargetOpcode::G_BITCAST, {Dst}, {Src}); Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -981,7 +981,7 @@ auto ZextInput = MIRBuilder.buildZExt(WideTy, SrcReg); - Register NextResult = I + 1 == NumOps && WideSize == DstSize ? DstReg : + Register NextResult = I + 1 == NumOps && WideTy == DstTy ? DstReg : MRI.createGenericVirtualRegister(WideTy); auto ShiftAmt = MIRBuilder.buildConstant(WideTy, Offset); @@ -992,6 +992,8 @@ if (WideSize > DstSize) MIRBuilder.buildTrunc(DstReg, ResultReg); + else if (WideTy != DstTy) + MIRBuilder.buildIntToPtr(DstReg, ResultReg); MI.eraseFromParent(); return Legalized; Index: test/CodeGen/AMDGPU/GlobalISel/legalize-merge-values.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/legalize-merge-values.mir +++ test/CodeGen/AMDGPU/GlobalISel/legalize-merge-values.mir @@ -1440,3 +1440,19 @@ %4:_(s68) = G_MERGE_VALUES %0, %1, %2, %3 S_NOP 0, implicit %4 ... +--- +name: test_merge_p3_s16_s16 +body: | + bb.0: + ; CHECK-LABEL: name: test_merge_p3_s16_s16 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 + ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[C]](s32) + ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[C1]](s32) + ; CHECK: [[MV:%[0-9]+]]:_(p3) = G_MERGE_VALUES [[TRUNC]](s16), [[TRUNC1]](s16) + ; CHECK: $vgpr0 = COPY [[MV]](p3) + %0:_(s16) = G_CONSTANT i16 0 + %1:_(s16) = G_CONSTANT i16 1 + %2:_(p3) = G_MERGE_VALUES %0, %1 + $vgpr0 = COPY %2 +... Index: unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp =================================================================== --- unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp @@ -1004,4 +1004,42 @@ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; } + +TEST_F(GISelMITest, WidenScalarMergeValuesPointer) { + if (!TM) + return; + + DefineLegalizerInfo(A, {}); + + AInfo Info(MF->getSubtarget()); + DummyGISelObserver Observer; + LegalizerHelper Helper(*MF, Info, Observer, B); + B.setInsertPt(*EntryMBB, EntryMBB->end()); + + const LLT S32 = LLT::scalar(32); + const LLT S64 = LLT::scalar(64); + const LLT P0 = LLT::pointer(0, 64); + + auto Lo = B.buildTrunc(S32, Copies[0]); + auto Hi = B.buildTrunc(S32, Copies[1]); + + auto Merge = B.buildMerge(P0, {Lo.getReg(0), Hi.getReg(0)}); + + EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, + Helper.widenScalar(*Merge, 1, S64)); + + auto CheckStr = R"( + CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC + CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC + CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]] + CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]] + CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 32 + CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]] + CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]] + CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64) + )"; + + EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; +} + } // namespace