diff options
author | Ruiling Song <ruiling.song@intel.com> | 2015-02-26 10:33:37 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2015-02-26 10:34:27 +0800 |
commit | d0496e65006002a75090bdc2c4099ff2cb3d8d44 (patch) | |
tree | 2450d1ebc1638f9c1ca203e7930f8c1c55e7bd9d | |
parent | dd4874bb3e4909225a36660360dfb8e2dcdc0d47 (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.cpp | 45 |
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()); |