[llvm] [SandboxIR] Add ShuffleVectorInst (PR #104891)

Jorge Gorbe Moya via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 20 16:40:37 PDT 2024


================
@@ -739,6 +740,360 @@ define void @foo(i8 %v0, i8 %v1, <2 x i8> %vec) {
       llvm::InsertElementInst::isValidOperands(LLVMArg0, LLVMArgVec, LLVMZero));
 }
 
+TEST_F(SandboxIRTest, ShuffleVectorInst) {
+  parseIR(C, R"IR(
+define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
+  %ins0 = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 0, i32 2>
+  ret void
+}
+)IR");
+  Function &LLVMF = *M->getFunction("foo");
+  sandboxir::Context Ctx(C);
+  auto &F = *Ctx.createFunction(&LLVMF);
+  auto *ArgV1 = F.getArg(0);
+  auto *ArgV2 = F.getArg(1);
+  auto *BB = &*F.begin();
+  auto It = BB->begin();
+  auto *SI = cast<sandboxir::ShuffleVectorInst>(&*It++);
+  auto *Ret = &*It++;
+
+  EXPECT_EQ(SI->getOpcode(), sandboxir::Instruction::Opcode::ShuffleVector);
+  EXPECT_EQ(SI->getType(), ArgV1->getType());
+  EXPECT_EQ(SI->getOperand(0), ArgV1);
+  EXPECT_EQ(SI->getOperand(1), ArgV2);
+  EXPECT_EQ(SI->getMaskValue(0), 0);
+  EXPECT_EQ(SI->getMaskValue(1), 2);
+  SI->commute();
+  EXPECT_EQ(SI->getOperand(0), ArgV2);
+  EXPECT_EQ(SI->getOperand(1), ArgV1);
+  EXPECT_THAT(SI->getShuffleMask(),
+              testing::ContainerEq(ArrayRef<int>({2, 0})));
+
+  auto *NewI1 =
+      cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
+          ArgV1, ArgV2, ArrayRef<int>({0, 2, 1, 3}), Ret, Ctx,
+          "NewShuffleBeforeRet"));
+  EXPECT_EQ(NewI1->getOperand(0), ArgV1);
+  EXPECT_EQ(NewI1->getOperand(1), ArgV2);
+  EXPECT_EQ(NewI1->getNextNode(), Ret);
+  EXPECT_TRUE(NewI1->changesLength());
+  EXPECT_TRUE(NewI1->increasesLength());
+
+  auto *NewI2 =
+      cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
+          ArgV1, ArgV2, ArrayRef<int>({0, 1}), BB, Ctx, "NewShuffleAtEndOfBB"));
+  EXPECT_EQ(NewI2->getPrevNode(), Ret);
+
+  auto *LLVMArgV1 = LLVMF.getArg(0);
+  auto *LLVMArgV2 = LLVMF.getArg(1);
+  ArrayRef<int> Mask({1, 2});
+  EXPECT_EQ(
+      sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV2, Mask),
+      llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV2, Mask));
+  EXPECT_EQ(sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV1, ArgV1),
+            llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV1,
+                                                     LLVMArgV1));
+
+  // The following functions check different mask properties. Note that most
+  // of these come in three different flavors: a method that checks the mask
+  // in the current instructions and two static member functions that check
+  // a mask given as an ArrayRef<int> or Constant*, so there's quite a bit of
+  // repetition in order to check all of them.
+  //
+  // Because we need masks of different lengths we can't simply reuse one of the
+  // instructions we have created above, so we'll create a new instruction for
+  // each test using this helper.
+  auto shuffleWithMask = [&](auto &&...Indices) {
----------------
slackito wrote:

Renamed to `CreateShuffleWithMask`

https://github.com/llvm/llvm-project/pull/104891


More information about the llvm-commits mailing list