[PATCH] D82961: [Scalarizer] Variable insert handling (PR46524)

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 1 07:00:28 PDT 2020


lebedev.ri created this revision.
lebedev.ri added reviewers: bjope, cameron.mcinally, arsenm, jdoerfert.
lebedev.ri added a project: LLVM.
Herald added subscribers: hiraditya, wdng.

I'm interested in taking the original C++ input,
for which we currently are stuck with an alloca
and producing roughly the lower IR,
with neither an alloca nor a vector ops:
https://godbolt.org/z/cRRWaJ

For that, as intermediate step, i'd to somehow perform scalarization.
As per @arsenmn suggestion, i'm trying to see if scalarizer can help me
avoid writing a bicycle.

I'm not sure if it's really intentional that variable insert is not handled currently.
If it really is, and is supposed to stay that way (?), i guess i could guard it..


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82961

Files:
  llvm/lib/Transforms/Scalar/Scalarizer.cpp
  llvm/test/Transforms/Scalarizer/basic.ll


Index: llvm/test/Transforms/Scalarizer/basic.ll
===================================================================
--- llvm/test/Transforms/Scalarizer/basic.ll
+++ llvm/test/Transforms/Scalarizer/basic.ll
@@ -363,19 +363,37 @@
   ret void
 }
 
-; Test that variable inserts aren't scalarized.
+; Test that variable inserts are scalarized.
 define void @f12(<4 x i32> *%dest, <4 x i32> *%src, i32 %index) {
-; CHECK: @f12(
-; CHECK: %val1 = insertelement <4 x i32> %val0, i32 1, i32 %index
-; CHECK-DAG: %val1.i0 = extractelement <4 x i32> %val1, i32 0
-; CHECK-DAG: %val1.i1 = extractelement <4 x i32> %val1, i32 1
-; CHECK-DAG: %val1.i2 = extractelement <4 x i32> %val1, i32 2
-; CHECK-DAG: %val1.i3 = extractelement <4 x i32> %val1, i32 3
-; CHECK-DAG: %val2.i0 = shl i32 1, %val1.i0
-; CHECK-DAG: %val2.i1 = shl i32 2, %val1.i1
-; CHECK-DAG: %val2.i2 = shl i32 3, %val1.i2
-; CHECK-DAG: %val2.i3 = shl i32 4, %val1.i3
-; CHECK: ret void
+; CHECK-LABEL: @f12(
+; CHECK: %dest.i0 = bitcast <4 x i32>* %dest to i32*
+; CHECK: %dest.i1 = getelementptr i32, i32* %dest.i0, i32 1
+; CHECK: %dest.i2 = getelementptr i32, i32* %dest.i0, i32 2
+; CHECK: %dest.i3 = getelementptr i32, i32* %dest.i0, i32 3
+; CHECK: %src.i0 = bitcast <4 x i32>* %src to i32*
+; CHECK: %val0.i0 = load i32, i32* %src.i0, align 16
+; CHECK: %src.i1 = getelementptr i32, i32* %src.i0, i32 1
+; CHECK: %val0.i1 = load i32, i32* %src.i1, align 4
+; CHECK: %src.i2 = getelementptr i32, i32* %src.i0, i32 2
+; CHECK: %val0.i2 = load i32, i32* %src.i2, align 8
+; CHECK: %src.i3 = getelementptr i32, i32* %src.i0, i32 3
+; CHECK: %val0.i3 = load i32, i32* %src.i3, align 4
+; CHECK: %index.is.0 = icmp eq i32 %index, 0
+; CHECK: %val1.i0 = select i1 %index.is.0, i32 1, i32 %val0.i0
+; CHECK: %index.is.1 = icmp eq i32 %index, 1
+; CHECK: %val1.i1 = select i1 %index.is.1, i32 1, i32 %val0.i1
+; CHECK: %index.is.2 = icmp eq i32 %index, 2
+; CHECK: %val1.i2 = select i1 %index.is.2, i32 1, i32 %val0.i2
+; CHECK: %index.is.3 = icmp eq i32 %index, 3
+; CHECK: %val1.i3 = select i1 %index.is.3, i32 1, i32 %val0.i3
+; CHECK: %val2.i0 = shl i32 1, %val1.i0
+; CHECK: %val2.i1 = shl i32 2, %val1.i1
+; CHECK: %val2.i2 = shl i32 3, %val1.i2
+; CHECK: %val2.i3 = shl i32 4, %val1.i3
+; CHECK: store i32 %val2.i0, i32* %dest.i0, align 16
+; CHECK: store i32 %val2.i1, i32* %dest.i1, align 4
+; CHECK: store i32 %val2.i2, i32* %dest.i2, align 8
+; CHECK: store i32 %val2.i3, i32* %dest.i3, align 4
   %val0 = load <4 x i32> , <4 x i32> *%src
   %val1 = insertelement <4 x i32> %val0, i32 1, i32 %index
   %val2 = shl <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %val1
Index: llvm/lib/Transforms/Scalar/Scalarizer.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/Scalarizer.cpp
+++ llvm/lib/Transforms/Scalar/Scalarizer.cpp
@@ -192,6 +192,7 @@
   bool visitGetElementPtrInst(GetElementPtrInst &GEPI);
   bool visitCastInst(CastInst &CI);
   bool visitBitCastInst(BitCastInst &BCI);
+  bool visitInsertElementInst(InsertElementInst &IEI);
   bool visitShuffleVectorInst(ShuffleVectorInst &SVI);
   bool visitPHINode(PHINode &PHI);
   bool visitLoadInst(LoadInst &LI);
@@ -743,6 +744,33 @@
   return true;
 }
 
+bool ScalarizerVisitor::visitInsertElementInst(InsertElementInst &IEI) {
+  VectorType *VT = dyn_cast<VectorType>(IEI.getType());
+  if (!VT)
+    return false;
+
+  unsigned NumElems = VT->getNumElements();
+  IRBuilder<> Builder(&IEI);
+  Scatterer Op0 = scatter(&IEI, IEI.getOperand(0));
+  Value *NewElt = IEI.getOperand(1);
+
+  Value *InsIdx = IEI.getOperand(2);
+  if (isa<Constant>(InsIdx))
+    return false;
+
+  ValueVector Res;
+  Res.resize(NumElems);
+
+  for (unsigned I = 0; I < NumElems; ++I) {
+    Res[I] = Builder.CreateSelect(
+        Builder.CreateICmpEQ(InsIdx, ConstantInt::get(InsIdx->getType(), I),
+                             InsIdx->getName() + ".is." + Twine(I)),
+        NewElt, Op0[I], IEI.getName() + ".i" + Twine(I));
+  }
+  gather(&IEI, Res);
+  return true;
+}
+
 bool ScalarizerVisitor::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
   VectorType *VT = dyn_cast<VectorType>(SVI.getType());
   if (!VT)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82961.274790.patch
Type: text/x-patch
Size: 4165 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200701/a46a311f/attachment.bin>


More information about the llvm-commits mailing list