Skip to content

Commit 7e9841d

Browse files
Brox Chenagainull
authored andcommitted
Fix the ptr.annotation generation in reverse translator (#1899)
Fix the ptr.annotation in reverse translator such that the generated pointer annotation call is being used properly in the IR. The IR generated from the previous code base is: %0 = xxx %1 = ptr.annotation %0 ... (left unused) %2 = load %0 ... while the expected form is: %0 = xxx %1 = ptr.annotation %0 ... %2 = load %1 ... Original commit: KhronosGroup/SPIRV-LLVM-Translator@6a581e1
1 parent 5a1c015 commit 7e9841d

File tree

2 files changed

+65
-12
lines changed

2 files changed

+65
-12
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,20 +1236,67 @@ Value *SPIRVToLLVM::oclTransConstantPipeStorage(
12361236
GlobalValue::NotThreadLocal, SPIRAS_Global);
12371237
}
12381238

1239+
namespace {
1240+
12391241
// A pointer annotation may have been generated for the operand. If the operand
12401242
// is used further in IR, it should be replaced with the intrinsic call result.
12411243
// Otherwise, the generated pointer annotation call is left unused.
1242-
static void replaceOperandWithAnnotationIntrinsicCallResult(Value *&V) {
1243-
if (Use *SingleUse = V->getSingleUndroppableUse()) {
1244-
if (auto *II = dyn_cast<IntrinsicInst>(SingleUse->getUser())) {
1245-
if (II->getIntrinsicID() == Intrinsic::ptr_annotation &&
1246-
II->getType() == V->getType())
1247-
// Overwrite the future operand with the intrinsic call result.
1248-
V = II;
1244+
static void replaceOperandWithAnnotationIntrinsicCallResult(Function *F,
1245+
Value *&V) {
1246+
1247+
SPIRVDBG(spvdbgs() << "\n"
1248+
<< "-------- REPLACE --------" << '\n';)
1249+
SPIRVDBG(dbgs() << "value: " << *V << '\n');
1250+
1251+
Value *BaseValue = nullptr;
1252+
IntrinsicInst *CallResult = nullptr;
1253+
1254+
auto SearchPtrAnn = [=](Value *BV, IntrinsicInst *&CR) {
1255+
CR = nullptr;
1256+
for (auto *Use : BV->users()) {
1257+
if (auto *II = dyn_cast<IntrinsicInst>(Use)) {
1258+
if (II->getIntrinsicID() == Intrinsic::ptr_annotation &&
1259+
II->getType() == BV->getType()) {
1260+
assert(CR == nullptr && "Multiple annotation created for same value");
1261+
CR = II;
1262+
}
1263+
}
1264+
}
1265+
return CR ? true : false;
1266+
};
1267+
1268+
if (SearchPtrAnn(V, CallResult)) {
1269+
BaseValue = V;
1270+
} else {
1271+
// scan def-use chain, skip bitcast and addrspacecast
1272+
// search for the closest floating ptr.annotation
1273+
auto *Inst = dyn_cast<Instruction>(V);
1274+
while (Inst && (isa<BitCastInst>(Inst) || isa<AddrSpaceCastInst>(Inst))) {
1275+
if ((Inst = dyn_cast<Instruction>(Inst->getOperand(0))) &&
1276+
SearchPtrAnn(Inst, CallResult)) {
1277+
BaseValue = Inst;
1278+
break;
1279+
}
12491280
}
12501281
}
1282+
1283+
// overwrite operand with intrinsic call result
1284+
if (CallResult) {
1285+
SPIRVDBG(dbgs() << "BaseValue: " << *BaseValue << '\n'
1286+
<< "CallResult: " << *CallResult << '\n');
1287+
DominatorTree DT(*F);
1288+
BaseValue->replaceUsesWithIf(CallResult, [&DT, &CallResult](Use &U) {
1289+
return DT.dominates(CallResult, U);
1290+
});
1291+
1292+
// overwrite V
1293+
if (V == BaseValue)
1294+
V = CallResult;
1295+
}
12511296
}
12521297

1298+
} // namespace
1299+
12531300
// Translate aliasing memory access masks for SPIRVLoad and SPIRVStore
12541301
// instructions. These masks are mapped on alias.scope and noalias
12551302
// metadata in LLVM. Translation of optional string operand isn't yet supported
@@ -1727,9 +1774,9 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
17271774
auto *Src = transValue(BS->getSrc(), F, BB);
17281775
auto *Dst = transValue(BS->getDst(), F, BB);
17291776
// A ptr.annotation may have been generated for the source variable.
1730-
replaceOperandWithAnnotationIntrinsicCallResult(Src);
1777+
replaceOperandWithAnnotationIntrinsicCallResult(F, Src);
17311778
// A ptr.annotation may have been generated for the destination variable.
1732-
replaceOperandWithAnnotationIntrinsicCallResult(Dst);
1779+
replaceOperandWithAnnotationIntrinsicCallResult(F, Dst);
17331780

17341781
bool isVolatile = BS->SPIRVMemoryAccess::isVolatile();
17351782
uint64_t AlignValue = BS->SPIRVMemoryAccess::getAlignment();
@@ -1747,7 +1794,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
17471794
SPIRVLoad *BL = static_cast<SPIRVLoad *>(BV);
17481795
auto *V = transValue(BL->getSrc(), F, BB);
17491796
// A ptr.annotation may have been generated for the source variable.
1750-
replaceOperandWithAnnotationIntrinsicCallResult(V);
1797+
replaceOperandWithAnnotationIntrinsicCallResult(F, V);
17511798

17521799
Type *Ty = transType(BL->getType());
17531800
LoadInst *LI = nullptr;

llvm-spirv/test/extensions/INTEL/SPV_INTEL_fpga_buffer_location/FPGABufferLocation.ll

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,23 @@ entry:
7373
store ptr addrspace(1) %arg_a, ptr addrspace(4) %arg_a.addr.ascast, align 8
7474
%a = getelementptr inbounds %struct.MyIP, ptr addrspace(4) %MyIP.ascast, i32 0, i32 0
7575
%0 = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %a, ptr getelementptr inbounds ([33 x i8], ptr @.str.4, i32 0, i32 0), ptr getelementptr inbounds ([9 x i8], ptr @.str.1, i32 0, i32 0), i32 7, ptr null)
76-
; CHECK-LLVM: call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %a, ptr @[[ANN_STR]], ptr undef, i32 undef, ptr undef)
7776
%b = load ptr addrspace(1), ptr addrspace(4) %arg_a.addr.ascast, align 8
7877
%1 = addrspacecast ptr addrspace(1) %b to ptr addrspace(4)
7978
store ptr addrspace(4) %1, ptr addrspace(4) %0, align 8
79+
; CHECK-LLVM: %[[INTRINSIC_CALL:[[:alnum:].]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %a, ptr @[[ANN_STR]], ptr undef, i32 undef, ptr undef)
80+
; CHECK-LLVM: %[[BITCAST_CALL1:[[:alnum:].]+]] = bitcast ptr addrspace(4) %[[INTRINSIC_CALL]] to ptr addrspace(4)
81+
; CHECK-LLVM: %[[BITCAST_CALL2:[[:alnum:].]+]] = bitcast ptr addrspace(4) %[[BITCAST_CALL1]] to ptr addrspace(4)
82+
; CHECK-LLVM: store ptr addrspace(4) %4, ptr addrspace(4) %[[BITCAST_CALL2]], align 8
8083
%this.addr.ascast.i = addrspacecast ptr %this.addr.i to ptr addrspace(4)
8184
store ptr addrspace(4) %MyIP.ascast, ptr addrspace(4) %this.addr.ascast.i, align 8
8285
%this1.i = load ptr addrspace(4), ptr addrspace(4) %this.addr.ascast.i, align 8
8386
%a.i = getelementptr inbounds %struct.MyIP, ptr addrspace(4) %this1.i, i32 0, i32 0
8487
%2 = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %a.i, ptr getelementptr inbounds ([19 x i8], ptr @.str.4, i32 0, i32 0), ptr getelementptr inbounds ([9 x i8], ptr @.str.1, i32 0, i32 0), i32 7, ptr null)
85-
; CHECK-LLVM: call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %a.i, ptr @[[ANN_STR]], ptr undef, i32 undef, ptr undef)
8688
%3 = load ptr addrspace(4), ptr addrspace(4) %2, align 8
89+
; CHECK-LLVM: %[[INTRINSIC_CALL:[[:alnum:].]+]] = call ptr addrspace(4) @llvm.ptr.annotation.p4.p0(ptr addrspace(4) %a.i, ptr @[[ANN_STR]], ptr undef, i32 undef, ptr undef)
90+
; CHECK-LLVM: %[[BITCAST_CALL1:[[:alnum:].]+]] = bitcast ptr addrspace(4) %[[INTRINSIC_CALL]] to ptr addrspace(4)
91+
; CHECK-LLVM: %[[BITCAST_CALL2:[[:alnum:].]+]] = bitcast ptr addrspace(4) %[[BITCAST_CALL1]] to ptr addrspace(4)
92+
; CHECK-LLVM: load ptr addrspace(4), ptr addrspace(4) %[[BITCAST_CALL2]], align 8
8793
%4 = load i32, ptr addrspace(4) %3, align 4
8894
%inc.i = add nsw i32 %4, 1
8995
store i32 %inc.i, ptr addrspace(4) %3, align 4

0 commit comments

Comments
 (0)