[Beignet] [PATCH] GBE: unify element type before insertelement in legalize pass.

Zhigang Gong zhigang.gong at linux.intel.com
Wed Feb 25 18:33:58 PST 2015


This patch LGTM, thanks for the quick fix.

On Thu, Feb 26, 2015 at 10:33:37AM +0800, Ruiling Song wrote:
> 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 at intel.com>
> ---
>  backend/src/llvm/ExpandLargeIntegers.cpp |   45 +++++++++++++++++++++++++++---
>  1 file changed, 41 insertions(+), 4 deletions(-)
> 
> diff --git a/backend/src/llvm/ExpandLargeIntegers.cpp b/backend/src/llvm/ExpandLargeIntegers.cpp
> index 194622c..912fda2 100644
> --- a/backend/src/llvm/ExpandLargeIntegers.cpp
> +++ b/backend/src/llvm/ExpandLargeIntegers.cpp
> @@ -347,7 +347,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);
> @@ -356,6 +356,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");
> @@ -422,15 +456,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());
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list