[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