summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuiling Song <ruiling.song@intel.com>2015-02-26 10:33:37 +0800
committerZhigang Gong <zhigang.gong@intel.com>2015-02-26 10:34:27 +0800
commitd0496e65006002a75090bdc2c4099ff2cb3d8d44 (patch)
tree2450d1ebc1638f9c1ca203e7930f8c1c55e7bd9d
parentdd4874bb3e4909225a36660360dfb8e2dcdc0d47 (diff)
GBE: unify element type before insertelement in legalize pass.
large integer type like i96 may be expanded to be low 64bit and high 32bit. When it is cast to <i32 x 3>, we should first make the expanded type to be of same type, here i32. insertelement could not insert element of different type. Then we can do insertelement one by one to generate the <i32 x 3> vector. This could fix the bug: https://bugs.freedesktop.org/show_bug.cgi?id=89167 Signed-off-by: Ruiling Song <ruiling.song@intel.com> Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r--backend/src/llvm/ExpandLargeIntegers.cpp45
1 files changed, 41 insertions, 4 deletions
diff --git a/backend/src/llvm/ExpandLargeIntegers.cpp b/backend/src/llvm/ExpandLargeIntegers.cpp
index aa86dde8..f7e59a56 100644
--- a/backend/src/llvm/ExpandLargeIntegers.cpp
+++ b/backend/src/llvm/ExpandLargeIntegers.cpp
@@ -354,7 +354,7 @@ static Value *buildVectorOrScalar(ConversionState &State, IRBuilder<> &IRB, Smal
}
}
-void getSplitedValue(ConversionState &State, Value *Val, SmallVector<Value *, 16> &Result) {
+static void getSplitedValue(ConversionState &State, Value *Val, SmallVector<Value *, 16> &Result) {
while (shouldConvert(Val)) {
ValuePair Convert = State.getConverted(Val);
Result.push_back(Convert.Lo);
@@ -363,6 +363,40 @@ void getSplitedValue(ConversionState &State, Value *Val, SmallVector<Value *, 16
Result.push_back(Val);
}
+// make all the elements in Src use the same llvm::Type, and return them in Dst
+static void unifyElementType(IRBuilder<> &IRB, SmallVector<Value *, 16> &Src, SmallVector<Value *, 16> &Dst) {
+ unsigned MinWidth = Src[0]->getType()->getPrimitiveSizeInBits();
+ bool Unified = true;
+ for (unsigned i = 0; i < Src.size(); i++) {
+ Type *Ty = Src[i]->getType();
+ unsigned BitWidth = Ty->getPrimitiveSizeInBits();
+ if(BitWidth != MinWidth) Unified = false;
+ if(BitWidth < MinWidth) MinWidth = BitWidth;
+ }
+
+ if (Unified) {
+ for (unsigned i = 0; i < Src.size(); i++)
+ Dst.push_back(Src[i]);
+ } else {
+ Type *IntTy = IntegerType::get(IRB.getContext(), 32);
+ Type *ElemTy = IntegerType::get(IRB.getContext(), MinWidth);
+ for (unsigned i = 0; i < Src.size(); i++) {
+ Type *Ty = Src[i]->getType();
+ unsigned Size = Ty->getPrimitiveSizeInBits();
+ assert((Size % MinWidth) == 0);
+
+ if (Size > MinWidth) {
+ VectorType *VecTy = VectorType::get(ElemTy, Size/MinWidth);
+ Value *Casted = IRB.CreateBitCast(Src[i], VecTy);
+ for (unsigned j = 0; j < Size/MinWidth; j++)
+ Dst.push_back(IRB.CreateExtractElement(Casted, ConstantInt::get(IntTy, j)));
+ } else {
+ Dst.push_back(Src[i]);
+ }
+ }
+ }
+}
+
static void convertInstruction(Instruction *Inst, ConversionState &State,
const DataLayout &DL) {
DEBUG(dbgs() << "Expanding Large Integer: " << *Inst << "\n");
@@ -429,15 +463,18 @@ static void convertInstruction(Instruction *Inst, ConversionState &State,
if (DstVec) {
// integer to vector, get all children and bitcast
SmallVector<Value *, 16> Split;
+ SmallVector<Value *, 16> Unified;
getSplitedValue(State, Operand, Split);
+ // unify element type, this is required by insertelement
+ unifyElementType(IRB, Split, Unified);
Value *vec = NULL;
- unsigned ElemNo = Split.size();
- Type *ElemTy = Split[0]->getType();
+ unsigned ElemNo = Unified.size();
+ Type *ElemTy = Unified[0]->getType();
for (unsigned i = 0; i < ElemNo; ++i) {
Value *tmp = vec ? vec : UndefValue::get(VectorType::get(ElemTy, ElemNo));
Value *idx = ConstantInt::get(IntTy, i);
- vec = IRB.CreateInsertElement(tmp, Split[i], idx);
+ vec = IRB.CreateInsertElement(tmp, Unified[i], idx);
}
if (vec->getType() != Cast->getType())
vec = IRB.CreateBitCast(vec, Cast->getType());