[llvm] 2004ab4 - MachineIRBuilder: Add buildMergeValues. NFC

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 13 00:45:43 PST 2023


Author: Diana Picus
Date: 2023-01-13T09:32:58+01:00
New Revision: 2004ab422a01b24c183f958b10ec4845aeb9b453

URL: https://github.com/llvm/llvm-project/commit/2004ab422a01b24c183f958b10ec4845aeb9b453
DIFF: https://github.com/llvm/llvm-project/commit/2004ab422a01b24c183f958b10ec4845aeb9b453.diff

LOG: MachineIRBuilder: Add buildMergeValues. NFC

Add a `buildMergeValues` method that unconditionally builds a
G_MERGE_VALUES instruction, as opposed to `buildMergeLikeInstr` which
may decide on a different opcode based on the input types.

I haven't audited all the uses of `buildMergeLikeInstr` to see if they
can be replaced with `buildMergeValues`, but I did find a couple of
obvious ones where we check that we're merging scalars right before
calling `buildMerge`.

This is a follow-up suggested in https://reviews.llvm.org/D140964

Differential Revision: https://reviews.llvm.org/D141373

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
    llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
    llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
    llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
    llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 16f63527456a..0f8f5662926d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -300,7 +300,7 @@ class LegalizationArtifactCombiner {
         for (unsigned i = 0; i < NumSrcs; ++i)
           SrcRegs[i] = SrcMerge->getSourceReg(i);
 
-        Builder.buildMergeLikeInstr(DstReg, SrcRegs);
+        Builder.buildMergeValues(DstReg, SrcRegs);
         UpdatedDefs.push_back(DstReg);
       } else {
         // Unable to combine

diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 08f240a6a563..e5b48d9d52c0 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -968,6 +968,21 @@ class MachineIRBuilder {
   /// Build and insert \p Res = IMPLICIT_DEF.
   MachineInstrBuilder buildUndef(const DstOp &Res);
 
+  /// Build and insert \p Res = G_MERGE_VALUES \p Op0, ...
+  ///
+  /// G_MERGE_VALUES combines the input elements contiguously into a larger
+  /// register. It should only be used when the destination register is not a
+  /// vector.
+  ///
+  /// \pre setBasicBlock or setMI must have been called.
+  /// \pre The entire register \p Res (and no more) must be covered by the input
+  ///      registers.
+  /// \pre The type of all \p Ops registers must be identical.
+  ///
+  /// \return a MachineInstrBuilder for the newly created instruction.
+  MachineInstrBuilder buildMergeValues(const DstOp &Res,
+                                       ArrayRef<Register> Ops);
+
   /// Build and insert \p Res = G_MERGE_VALUES \p Op0, ...
   ///               or \p Res = G_BUILD_VECTOR \p Op0, ...
   ///               or \p Res = G_CONCAT_VECTORS \p Op0, ...

diff  --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index d59dfc826934..89872259cfca 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -388,7 +388,7 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
 
     unsigned SrcSize = PartLLT.getSizeInBits().getFixedValue() * Regs.size();
     if (SrcSize == OrigTy.getSizeInBits())
-      B.buildMergeLikeInstr(OrigRegs[0], Regs);
+      B.buildMergeValues(OrigRegs[0], Regs);
     else {
       auto Widened = B.buildMergeLikeInstr(LLT::scalar(SrcSize), Regs);
       B.buildTrunc(OrigRegs[0], Widened);

diff  --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index a6148a6985a3..9100e064f30f 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -597,6 +597,16 @@ MachineInstrBuilder MachineIRBuilder::buildUndef(const DstOp &Res) {
   return buildInstr(TargetOpcode::G_IMPLICIT_DEF, {Res}, {});
 }
 
+MachineInstrBuilder MachineIRBuilder::buildMergeValues(const DstOp &Res,
+                                                       ArrayRef<Register> Ops) {
+  // Unfortunately to convert from ArrayRef<LLT> to ArrayRef<SrcOp>,
+  // we need some temporary storage for the DstOp objects. Here we use a
+  // sufficiently large SmallVector to not go through the heap.
+  SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
+  assert(TmpVec.size() > 1);
+  return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, TmpVec);
+}
+
 MachineInstrBuilder
 MachineIRBuilder::buildMergeLikeInstr(const DstOp &Res,
                                       ArrayRef<Register> Ops) {

diff  --git a/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp b/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
index 4d445589043a..421aaec07cb2 100644
--- a/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
@@ -361,6 +361,39 @@ TEST_F(AArch64GISelMITest, BuildMergeLikeInstr) {
   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
+using MachineIRBuilderDeathTest = AArch64GISelMITest;
+
+TEST_F(MachineIRBuilderDeathTest, BuildMergeValues) {
+  setUp();
+  if (!TM)
+    return;
+
+  LLT S32 = LLT::scalar(32);
+  Register RegC0 = B.buildConstant(S32, 0).getReg(0);
+  Register RegC1 = B.buildConstant(S32, 1).getReg(0);
+  Register RegC2 = B.buildConstant(S32, 2).getReg(0);
+  Register RegC3 = B.buildConstant(S32, 3).getReg(0);
+
+  // Merging scalar constants should produce a G_MERGE_VALUES.
+  B.buildMergeValues(LLT::scalar(128), {RegC0, RegC1, RegC2, RegC3});
+
+  // Using a vector destination type should assert.
+  LLT V2x32 = LLT::fixed_vector(2, 32);
+  EXPECT_DEBUG_DEATH(
+      B.buildMergeValues(V2x32, {RegC0, RegC1}),
+      "vectors should be built with G_CONCAT_VECTOR or G_BUILD_VECTOR");
+
+  auto CheckStr = R"(
+  ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+  ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+  ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+  ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+  ; CHECK: {{%[0-9]+}}:_(s128) = G_MERGE_VALUES [[C0]]:_(s32), [[C1]]:_(s32), [[C2]]:_(s32), [[C3]]:_(s32)
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
 TEST_F(AArch64GISelMITest, BuildAddoSubo) {
   setUp();
   if (!TM)


        


More information about the llvm-commits mailing list