Skip to content

Commit

Permalink
fix bitcast from struct to scalar (#1181)
Browse files Browse the repository at this point in the history
Fix #1178
Fix #1179
  • Loading branch information
rjodinchr authored Aug 17, 2023
1 parent 93ea850 commit 9688056
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 12 deletions.
30 changes: 26 additions & 4 deletions lib/BitcastUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,26 @@ Value *ConvertValue(Value *src, Type *dst_type, IRBuilder<> &builder) {
return nullptr;
}

// 'Values' is expected to contain elements that will compose struct of type
// 'Ty'.
// 'Values' is also the output of this function, containing arrays of type 'Ty'.
void InsertInArrayLikeStruct(IRBuilder<> &Builder, StructType *Ty,
SmallVector<Value *, 8> &Values) {
DEBUG_FCT_TY_VALUES(Ty, Values);
unsigned StructNumEles = Ty->getNumElements();
assert(Ty->getElementType(0) == Values[0]->getType());
assert(Values.size() % StructNumEles == 0);
unsigned NumArrays = Values.size() / StructNumEles;
for (unsigned i = 0; i < NumArrays; i++) {
Value *Ret = PoisonValue::get(Ty);
for (unsigned j = 0; j < StructNumEles; j++) {
Ret = Builder.CreateInsertValue(Ret, Values[i * StructNumEles + j], {j});
}
Values[i] = Ret;
}
Values.resize(NumArrays);
}

// 'Values' is expected to contain elements that will compose arrays of type
// 'Ty'.
// 'Values' is also the output of this function, containing arrays of type 'Ty'.
Expand Down Expand Up @@ -705,14 +725,11 @@ void ConvertScalarIntoVector(FixedVectorType *Ty, IRBuilder<> &Builder,
BitcastValues(Builder, Ty, Values);
}

// 'Values' is expected to contain scalar elements.
// Return the scalar values of type 'Ty' into 'Values'.
void ConvertScalarIntoScalar(Type *Ty, IRBuilder<> &Builder,
SmallVector<Value *, 8> &Values) {
DEBUG_FCT_TY_VALUES(Ty, Values);
Type *ValueTy = Values[0]->getType();
assert(!Ty->isVectorTy() && !Ty->isArrayTy() && !ValueTy->isVectorTy() &&
!ValueTy->isArrayTy());

if (Ty == ValueTy) {
return;
Expand Down Expand Up @@ -755,7 +772,12 @@ void ConvertInto(Type *Ty, IRBuilder<> &Builder,
ConvertScalarIntoVector(VecTy, Builder, Values);
}
} else if (auto StructTy = dyn_cast<StructType>(Ty)) {
ConvertScalarIntoScalar(StructTy, Builder, Values);
if (IsArrayLike(StructTy)) {
ConvertScalarIntoScalar(StructTy->getElementType(0), Builder, Values);
InsertInArrayLikeStruct(Builder, StructTy, Values);
} else {
ConvertScalarIntoScalar(StructTy, Builder, Values);
}
} else {
Type *EleTy = GetEleType(Ty);
if (ValueTy->isVectorTy()) {
Expand Down
26 changes: 26 additions & 0 deletions test/PointerCasts/issue-1178.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: clspv %s -o %t.spv
// RUN: spirv-dis %t.spv -o %t.spvasm
// RUN: spirv-val %t.spv --target-env spv1.0

struct E {
int i1, i2, i3;
};

struct S {
int i1, i2;
struct E e1, e2;
};

kernel void Kernel0(global struct S *s) {
s->e1 = s->e2;
s->i1 = 0;
}

kernel void Kernel1(global struct S *s) {
s->e1 = s->e2;
s->i2 = 0;
}
kernel void Kernel2(global struct S *s) {
s->e1 = s->e2;
s->i2 = s->i1;
}
25 changes: 25 additions & 0 deletions test/PointerCasts/issue-1179.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: clspv %s -o %t.spv -physical-storage-buffers -arch=spir64 -cl-kernel-arg-info
// RUN: spirv-dis %t.spv -o %t.spvasm
// RUN: spirv-val %t.spv --target-env spv1.0

struct E {
int i1, i2, i3, i4;
};

struct S {
int Shift;
struct E e[3];
};

kernel void Kernel0(global struct S *s) { s->e[0] = s->e[1]; }
kernel void Kernel1(global struct S *s) {
struct E e = s->e[1];
s->e[0] = e;
}
kernel void Kernel2(global struct S *s) { s->e[1] = s->e[0]; }
kernel void Kernel3(global struct S *s) {
struct E e = s->e[0];
s->e[1] = e;
}
kernel void Kernel4(global struct S *s) { s->e[1] = s->e[2]; }
kernel void Kernel5(global struct S *s) { s->e[2] = s->e[1]; }
16 changes: 8 additions & 8 deletions test/PointerCasts/opaque_load_store_struct_i64_4.ll
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
; CHECK: [[shl:%[a-zA-Z0-9_.]+]] = shl i64 [[zext1_3]], 56
; CHECK: [[or:%[a-zA-Z0-9_.]+]] = or i64 [[or4]], [[shl]]

; CHECK: [[trunc:%[a-zA-Z0-9_.]+]] = trunc i64 [[or]] to i32
; CHECK: [[insert:%[a-zA-Z0-9_.]+]] = insertvalue { i32 } poison, i32 [[trunc]], 0
; CHECK: [[insert0:%[a-zA-Z0-9_.]+]] = insertvalue [[out]] poison, { i32 } [[insert]], 0
; CHECK: [[shr:%[a-zA-Z0-9_.]+]] = lshr i64 [[or]], 32
; CHECK: [[trunc:%[a-zA-Z0-9_.]+]] = trunc i64 [[shr]] to i32
; CHECK: [[insert:%[a-zA-Z0-9_.]+]] = insertvalue { i32 } poison, i32 [[trunc]], 0
; CHECK: [[insert1:%[a-zA-Z0-9_.]+]] = insertvalue [[out]] [[insert0]], { i32 } [[insert]], 1
; CHECK: store [[out]] [[insert1]], ptr addrspace(1)
; CHECK: [[bitcast:%[a-zA-Z0-9_.]+]] = bitcast i64 [[or]] to <2 x i32>
; CHECK: [[extract0:%[a-zA-Z0-9_.]+]] = extractelement <2 x i32> [[bitcast]], i64 0
; CHECK: [[extract1:%[a-zA-Z0-9_.]+]] = extractelement <2 x i32> [[bitcast]], i64 1
; CHECK: [[insert0:%[a-zA-Z0-9_.]+]] = insertvalue { i32 } poison, i32 [[extract0]], 0
; CHECK: [[insert1:%[a-zA-Z0-9_.]+]] = insertvalue { i32 } poison, i32 [[extract1]], 0
; CHECK: [[insert2:%[a-zA-Z0-9_.]+]] = insertvalue [[out]] poison, { i32 } [[insert0]], 0
; CHECK: [[insert3:%[a-zA-Z0-9_.]+]] = insertvalue [[out]] [[insert2]], { i32 } [[insert1]], 1
; CHECK: store [[out]] [[insert3]], ptr addrspace(1)

target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spir-unknown-unknown"
Expand Down

0 comments on commit 9688056

Please sign in to comment.