Skip to content

Commit 7b4ea7e

Browse files
authored
fix infertype of phinode (#1442)
When incoming values of phinode do not match the inferred type of the phi node from users, keep the smallest type to make sure types can be lowered. This is fixing a bug found using tensorflow lite leading to an invalid SPIR-V code generated by clspv.
1 parent 9737855 commit 7b4ea7e

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

lib/Types.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,11 @@ Type *clspv::InferType(Value *v, LLVMContext &context,
426426
for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) {
427427
(*cache)[phi] = phi_ty;
428428
auto IncValTy = InferType(phi->getIncomingValue(i), context, cache);
429-
phi_ty = SmallerTypeNotAliasing(DL, phi_ty, IncValTy);
429+
if (phi_ty && IncValTy &&
430+
BitcastUtils::SizeInBits(DL, phi_ty) >
431+
BitcastUtils::SizeInBits(DL, IncValTy)) {
432+
phi_ty = IncValTy;
433+
}
430434
}
431435
}
432436
cache->erase(phi);

test/PointerCasts/phi-from-gep.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,22 @@ loop:
125125
exit:
126126
ret void
127127
}
128+
129+
define spir_kernel void @test6(ptr addrspace(1) %buf, i32 %cst, i1 %cond) {
130+
entry:
131+
; CHECK: entry
132+
; CHECK-NEXT: [[gep:%[^ ]+]] = getelementptr { [0 x i32] }, ptr addrspace(1) %buf, i32 0, i32 0, i32 %cst
133+
; CHECK-NEXT: br label %loop
134+
%0 = getelementptr { [0 x i32] }, ptr addrspace(1) %buf, i32 0, i32 0, i32 0
135+
%gep = getelementptr inbounds nuw i32, ptr addrspace(1) %0, i32 %cst
136+
br label %loop
137+
loop:
138+
; CHECK: loop
139+
; CHECK-NEXT: [[phi:%[^ ]+]] = phi ptr addrspace(1) [ [[gep]], %entry ], [ [[gep2:%[^ ]+]], %loop ]
140+
; CHECK-NEXT: [[gep2]] = getelementptr <4 x i32>, ptr addrspace(1) [[phi]], i32 4, i32 0
141+
%phi = phi ptr addrspace(1) [ %gep, %entry ], [ %gep2, %loop ]
142+
%gep2 = getelementptr <4 x i32>, ptr addrspace(1) %phi, i32 4
143+
br i1 %cond, label %exit, label %loop
144+
exit:
145+
ret void
146+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: clspv %s -o %t.spv
2+
// RUN: spirv-dis %t.spv -o %t.spvasm
3+
// RUN: spirv-val %t.spv --target-env spv1.0
4+
// RUN: FileCheck %s < %t.spvasm
5+
6+
// CHECK: [[uint:%[^ ]+]] = OpTypeInt 32 0
7+
// CHECK: [[runtime:%[^ ]+]] = OpTypeRuntimeArray [[uint]]
8+
// CHECK: [[struct:%[^ ]+]] = OpTypeStruct [[runtime]]
9+
// CHECK: [[ptr:%[^ ]+]] = OpTypePointer StorageBuffer [[struct]]
10+
// CHECK: [[uint_ptr:%[^ ]+]] = OpTypePointer StorageBuffer [[uint]]
11+
// CHECK: [[var:%[^ ]+]] = OpVariable [[ptr]] StorageBuffer
12+
// CHECK: [[gep:%[^ ]+]] = OpAccessChain [[uint_ptr]] [[var]]
13+
// CHECK: [[phi:%[^ ]+]] = OpPhi [[uint_ptr]] [[gep]] [[label:%[^ ]+]] [[gep2:%[^ ]+]] [[label2:%[^ ]+]]
14+
// CHECK: [[gep2]] = OpPtrAccessChain [[uint_ptr]] [[phi]]
15+
16+
17+
void kernel foo(__global uint* buf, uint cst) {
18+
size_t gid = get_global_id(0);
19+
__global uint4* buf4 = buf + gid * 4 * cst;
20+
uint acc = 0;
21+
do {
22+
acc += buf4[0].x;
23+
buf4 += 4;
24+
} while (cst--);
25+
buf[gid] = acc;
26+
}

0 commit comments

Comments
 (0)