Skip to content

Commit 37d0063

Browse files
[SPIR-V] Ensure that internal intrinsic functions for PHI's operand are inserted at the correct positions (llvm#92316)
This PR is to ensure that internal intrinsic functions for PHI's operand are inserted at the correct positions and don't break rules of instruction domination and PHI nodes grouping at top of basic block.
1 parent 5b7088c commit 37d0063

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static bool isAggrToReplace(const Value *V) {
174174

175175
static void setInsertPointSkippingPhis(IRBuilder<> &B, Instruction *I) {
176176
if (isa<PHINode>(I))
177-
B.SetInsertPoint(I->getParent(), I->getParent()->getFirstInsertionPt());
177+
B.SetInsertPoint(I->getParent()->getFirstNonPHIOrDbgOrAlloca());
178178
else
179179
B.SetInsertPoint(I);
180180
}
@@ -491,7 +491,7 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(Instruction *I) {
491491
if (Instruction *User = dyn_cast<Instruction>(Op->use_begin()->get()))
492492
setInsertPointSkippingPhis(B, User->getNextNode());
493493
else
494-
B.SetInsertPoint(I);
494+
setInsertPointSkippingPhis(B, I);
495495
Value *OpTyVal = Constant::getNullValue(KnownElemTy);
496496
Type *OpTy = Op->getType();
497497
if (!Ty) {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
; The goal of the test is to check that internal intrinsic functions for PHI's
2+
; operand are inserted at the correct positions, and don't break rules of
3+
; instruction domination and PHI nodes grouping at top of basic block.
4+
5+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
6+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
7+
8+
; CHECK-DAG: OpName %[[#Foo:]] "foo"
9+
; CHECK-DAG: OpName %[[#Bar:]] "bar"
10+
; CHECK: %[[#Foo]] = OpFunction
11+
; CHECK: OpPhi
12+
; CHECK-NEXT: OpPhi
13+
; CHECK-NEXT: OpPhi
14+
; CHECK-NEXT: OpPhi
15+
; CHECK: %[[#Bar]] = OpFunction
16+
; CHECK: OpPhi
17+
; CHECK-NEXT: OpPhi
18+
; CHECK-NEXT: OpPhi
19+
; CHECK-NEXT: OpPhi
20+
21+
%struct = type { i64, i64 }
22+
23+
define spir_kernel void @foo(i64 %arg_val, ptr addrspace(4) byval(%struct) %arg_ptr) {
24+
entry:
25+
%fl = icmp eq i64 %arg_val, 0
26+
br i1 %fl, label %ok, label %err
27+
28+
err:
29+
br label %ok
30+
31+
ok:
32+
%r1 = phi i64 [ undef, %err ], [ %arg_val, %entry ]
33+
%r2 = phi i64 [ undef, %err ], [ %arg_val, %entry ]
34+
%r3 = phi ptr addrspace(4) [ undef, %err ], [ %arg_ptr, %entry ]
35+
%r4 = phi ptr addrspace(4) [ undef, %err ], [ %arg_ptr, %entry ]
36+
br label %exit
37+
38+
exit:
39+
ret void
40+
}
41+
42+
define spir_kernel void @bar(i64 %arg_val, i64 %arg_val_def, ptr addrspace(4) byval(%struct) %arg_ptr, ptr addrspace(4) %arg_ptr_def) {
43+
entry:
44+
%fl = icmp eq i64 %arg_val, 0
45+
br i1 %fl, label %ok, label %err
46+
47+
err:
48+
br label %ok
49+
50+
ok:
51+
%r1 = phi i64 [ %arg_val_def, %err ], [ %arg_val, %entry ]
52+
%r2 = phi i64 [ %arg_val_def, %err ], [ %arg_val, %entry ]
53+
%r3 = phi ptr addrspace(4) [ %arg_ptr_def, %err ], [ %arg_ptr, %entry ]
54+
%r4 = phi ptr addrspace(4) [ %arg_ptr_def, %err ], [ %arg_ptr, %entry ]
55+
br label %exit
56+
57+
exit:
58+
ret void
59+
}

0 commit comments

Comments
 (0)