[PATCH] IntegerDivision: Handle vectors in expandDivision() and expandRemainder()

Tom Stellard thomas.stellard at amd.com
Wed Sep 17 07:20:35 PDT 2014


This will be used and tested in a future commit to the R600 backend.
---
 lib/Transforms/Utils/IntegerDivision.cpp | 45 +++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/lib/Transforms/Utils/IntegerDivision.cpp b/lib/Transforms/Utils/IntegerDivision.cpp
index 9f91eeb..66133f6 100644
--- a/lib/Transforms/Utils/IntegerDivision.cpp
+++ b/lib/Transforms/Utils/IntegerDivision.cpp
@@ -366,6 +366,31 @@ static Value *generateUnsignedDivisionCode(Value *Dividend, Value *Divisor,
   return Q_5;
 }
 
+static void splitVector(BinaryOperator *I,
+                        SmallVectorImpl<BinaryOperator*> &Scalars) {
+
+  Type *Ty = I->getType();
+  unsigned NumElements = Ty->getVectorNumElements();
+
+  IRBuilder<> Builder(I);
+
+  Value *Op0 = I->getOperand(0);
+  Value *Op1 = I->getOperand(1);
+  Type *I32Ty = Type::getInt32Ty(I->getContext());
+  Value *Vec = UndefValue::get(Ty);
+  for (unsigned i = 0, e = NumElements; i != e; ++i) {
+    Value *Idx = Constant::getIntegerValue(I32Ty, APInt(32, i));
+    Value *LHS = Builder.CreateExtractElement(Op0, Idx);
+    Value *RHS = Builder.CreateExtractElement(Op1, Idx);
+    Value *Scalar = Builder.CreateBinOp(I->getOpcode(), LHS, RHS);
+    Vec = Builder.CreateInsertElement(Vec, Scalar, Idx);
+    Scalars.push_back(cast<BinaryOperator>(Scalar));
+  }
+  I->replaceAllUsesWith(Vec);
+  I->dropAllReferences();
+  I->eraseFromParent();
+}
+
 /// Generate code to calculate the remainder of two integers, replacing Rem with
 /// the generated code. This currently generates code using the udiv expansion,
 /// but future work includes generating more specialized code, e.g. when more
@@ -381,8 +406,14 @@ bool llvm::expandRemainder(BinaryOperator *Rem) {
   IRBuilder<> Builder(Rem);
 
   Type *RemTy = Rem->getType();
-  if (RemTy->isVectorTy())
-    llvm_unreachable("Div over vectors not supported");
+  if (RemTy->isVectorTy()) {
+    SmallVector<BinaryOperator*, 8> Scalars;
+    splitVector(Rem, Scalars);
+    for (BinaryOperator *ScalarRem : Scalars) {
+      expandRemainder(ScalarRem);
+    }
+    return true;
+  }
 
   unsigned RemTyBitWidth = RemTy->getIntegerBitWidth();
 
@@ -439,8 +470,14 @@ bool llvm::expandDivision(BinaryOperator *Div) {
   IRBuilder<> Builder(Div);
 
   Type *DivTy = Div->getType();
-  if (DivTy->isVectorTy())
-    llvm_unreachable("Div over vectors not supported");
+  if (DivTy->isVectorTy()) {
+    SmallVector<BinaryOperator*, 8> Scalars;
+    splitVector(Div, Scalars);
+    for (BinaryOperator *ScalarDiv : Scalars) {
+      expandDivision(ScalarDiv);
+    }
+    return true;
+  }
 
   unsigned DivTyBitWidth = DivTy->getIntegerBitWidth();
 
-- 
1.8.5.5




More information about the llvm-commits mailing list