Skip to content

Commit

Permalink
Fix translation of llvm.ptr.annotation (intel#678)
Browse files Browse the repository at this point in the history
This patch follows from 71039dd3c5dbfafab78f6b86a5bb06ba2af93c89

* Replaced the destination operand with the result of its intrinsic call for store inst.
* Replaced the read-from operand with the result of its intrinsic call for load inst.
  • Loading branch information
vmaksimo authored and vladimirlaz committed Aug 24, 2020
1 parent c0fe5ad commit 7c0f43c
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 22 deletions.
33 changes: 23 additions & 10 deletions llvm-spirv/lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,20 @@ Value *SPIRVToLLVM::oclTransConstantPipeStorage(
GlobalValue::NotThreadLocal, SPIRAS_Global);
}

// A pointer annotation may have been generated for the operand. If the operand
// is used further in IR, it should be replaced with the intrinsic call result.
// Otherwise, the generated pointer annotation call is left unused.
static void replaceOperandWithAnnotationIntrinsicCallResult(Value *&V) {
if (Use *SingleUse = V->getSingleUndroppableUse()) {
if (auto *II = dyn_cast<IntrinsicInst>(SingleUse->getUser())) {
if (II->getIntrinsicID() == Intrinsic::ptr_annotation &&
II->getType() == V->getType())
// Overwrite the future operand with the intrinsic call result.
V = II;
}
}
}

/// For instructions, this function assumes they are created in order
/// and appended to the given basic block. An instruction may use a
/// instruction from another BB which has not been translated. Such
Expand Down Expand Up @@ -1764,15 +1778,11 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
StoreInst *SI = nullptr;
auto *Src = transValue(BS->getSrc(), F, BB);
auto *Dst = transValue(BS->getDst(), F, BB);
// A pointer annotation may have been generated for the source variable.
if (Use *SingleUse = Src->getSingleUndroppableUse()) {
if (auto *II = dyn_cast<IntrinsicInst>(SingleUse->getUser())) {
if (II->getIntrinsicID() == Intrinsic::ptr_annotation &&
II->getType() == Src->getType())
// Overwrite the future store operand with the intrinsic call result.
Src = II;
}
}
// A ptr.annotation may have been generated for the source variable.
replaceOperandWithAnnotationIntrinsicCallResult(Src);
// A ptr.annotation may have been generated for the destination variable.
replaceOperandWithAnnotationIntrinsicCallResult(Dst);

bool isVolatile = BS->SPIRVMemoryAccess::isVolatile();
uint64_t AlignValue = BS->SPIRVMemoryAccess::getAlignment();
if (0 == AlignValue)
Expand All @@ -1786,7 +1796,10 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,

case OpLoad: {
SPIRVLoad *BL = static_cast<SPIRVLoad *>(BV);
auto V = transValue(BL->getSrc(), F, BB);
auto *V = transValue(BL->getSrc(), F, BB);
// A ptr.annotation may have been generated for the source variable.
replaceOperandWithAnnotationIntrinsicCallResult(V);

Type *Ty = V->getType()->getPointerElementType();
LoadInst *LI = nullptr;
uint64_t AlignValue = BL->SPIRVMemoryAccess::getAlignment();
Expand Down
40 changes: 32 additions & 8 deletions llvm-spirv/test/transcoding/IntelFPGAMemoryAccesses.ll
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
; y = __builtin_intel_fpga_mem(&C->Field2, 0, 127);
; z = __builtin_intel_fpga_mem(C, BURST_COAL | CACHE_SIZE_FLAG | DONT_STATICALLY_COAL | PREFETCH, 127);
; t = __builtin_intel_fpga_mem((double *) A, BURST_COAL | CACHE_SIZE_FLAG, 0);
; *__builtin_intel_fpga_mem(A, BURST_COAL | CACHE_SIZE_FLAG, 0) = 5;
; int s = *__builtin_intel_fpga_mem(B, DONT_STATICALLY_COAL | PREFETCH, 0);
; }
;
; template <typename name, typename Func>
Expand Down Expand Up @@ -81,6 +83,8 @@ target triple = "spir64-unknown-unknown-sycldevice"
@.str.6 = private unnamed_addr constant [28 x i8] c"{params:15}{cache-size:127}\00", section "llvm.metadata"
; TODO: Investigate why the same global annotation string shows up twice in backwards translation.
; CHECK-LLVM: [[PARAM_3_CACHE_0_DOUBLE:@[a-z0-9_.]+]] = {{.*}}{params:3}{cache-size:0}
; CHECK-LLVM: [[PARAM_3_CACHE_0_DOUBLE2:@[a-z0-9_.]+]] = {{.*}}{params:3}{cache-size:0}
; CHECK-LLVM: [[PARAM_12_CACHE_0_DOUBLE:@[a-z0-9_.]+]] = {{.*}}{params:12}

; Function Attrs: norecurse nounwind
define spir_kernel void @_ZTSZ4mainE11fake_kernel() #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !4 !kernel_arg_type !4 !kernel_arg_base_type !4 !kernel_arg_type_qual !4 {
Expand Down Expand Up @@ -142,10 +146,12 @@ entry:
; CHECK-LLVM: %[[INT_VAR:[[:alnum:].]+]] = alloca i32 addrspace(4)*, align 8
; CHECK-LLVM: %[[STRUCT_VAR:[[:alnum:].]+]] = alloca %struct{{.*}}State addrspace(4)*, align 8
; CHECK-LLVM: %[[DOUBLE_VAR:[[:alnum:].]+]] = alloca double addrspace(4)*, align 8
; CHECK-LLVM: %[[INT_VAR_1:[[:alnum:].]+]] = alloca i32, align 4
%x = alloca float addrspace(4)*, align 8
%y = alloca i32 addrspace(4)*, align 8
%z = alloca %struct._ZTS5State.State addrspace(4)*, align 8
%t = alloca double addrspace(4)*, align 8
%s = alloca i32, align 4
store float addrspace(4)* %A, float addrspace(4)** %A.addr, align 8, !tbaa !5
store i32 addrspace(4)* %B, i32 addrspace(4)** %B.addr, align 8, !tbaa !5
store %struct._ZTS5State.State addrspace(4)* %C, %struct._ZTS5State.State addrspace(4)** %C.addr, align 8, !tbaa !5
Expand Down Expand Up @@ -206,14 +212,32 @@ entry:
%17 = bitcast float addrspace(4)* %16 to double addrspace(4)*
%18 = call double addrspace(4)* @llvm.ptr.annotation.p4f64(double addrspace(4)* %17, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i32 0, i32 0), i32 0) #6
store double addrspace(4)* %18, double addrspace(4)** %t, align 8, !tbaa !5
%19 = bitcast double addrspace(4)** %t to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %19) #5
%20 = bitcast %struct._ZTS5State.State addrspace(4)** %z to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %20) #5
%21 = bitcast i32 addrspace(4)** %y to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %21) #5
%22 = bitcast float addrspace(4)** %x to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %22) #5
; CHECK-LLVM: %[[FLOAT_FUNC_PARAM_LOAD:[[:alnum:].]+]] = load float addrspace(4)*, float addrspace(4)** %[[FLOAT_FUNC_PARAM]]
; CHECK-LLVM: %[[INTRINSIC_CALL:[[:alnum:].]+]] = call float addrspace(4)* @llvm.ptr.annotation.p4f32(float addrspace(4)* %[[FLOAT_FUNC_PARAM_LOAD]], i8* getelementptr inbounds ({{.*}} [[PARAM_3_CACHE_0_DOUBLE2]]
; CHECK-LLVM: store float 5.000000e+00, float addrspace(4)* %[[INTRINSIC_CALL]]
%19 = load float addrspace(4)*, float addrspace(4)** %A.addr, align 8, !tbaa !5
%20 = call float addrspace(4)* @llvm.ptr.annotation.p4f32(float addrspace(4)* %19, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i32 0, i32 0), i32 0) #6
store float 5.000000e+00, float addrspace(4)* %20, align 4, !tbaa !5
%21 = bitcast i32* %s to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* %21) #5
; CHECK-LLVM: %[[INT1_FUNC_PARAM_LOAD:[[:alnum:].]+]] = load i32 addrspace(4)*, i32 addrspace(4)** %[[INT_FUNC_PARAM]]
; CHECK-LLVM: %[[INTRINSIC_CALL:[[:alnum:].]+]] = call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %[[INT1_FUNC_PARAM_LOAD]], i8* getelementptr inbounds ({{.*}} [[PARAM_12_CACHE_0_DOUBLE]]
; CHECK-LLVM: %[[INTRINSIC_RESULT_LOAD:[[:alnum:].]+]] = load i32, i32 addrspace(4)* %[[INTRINSIC_CALL]]
; CHECK-LLVM: store i32 %[[INTRINSIC_RESULT_LOAD]], i32* %[[INT_VAR_1]]
%22 = load i32 addrspace(4)*, i32 addrspace(4)** %B.addr, align 8, !tbaa !5
%23 = call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %22, i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i32 0, i32 0), i32 0) #6
%24 = load i32, i32 addrspace(4)* %23, align 4, !tbaa !5
store i32 %24, i32* %s, align 4, !tbaa !5
%25 = bitcast i32* %s to i8*
call void @llvm.lifetime.end.p0i8(i64 4, i8* %25) #5
%26 = bitcast double addrspace(4)** %t to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %26) #5
%27 = bitcast %struct._ZTS5State.State addrspace(4)** %z to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %27) #5
%28 = bitcast i32 addrspace(4)** %y to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %28) #5
%29 = bitcast float addrspace(4)** %x to i8*
call void @llvm.lifetime.end.p0i8(i64 8, i8* %29) #5
ret void
}

Expand Down
8 changes: 4 additions & 4 deletions llvm-spirv/test/transcoding/intel_fpga_lsu_optimized.ll
Original file line number Diff line number Diff line change
Expand Up @@ -91,29 +91,29 @@ entry:
; CHECK-LLVM: [[PTR_i:[%0-9a-z.]+]] = getelementptr inbounds i32, i32 addrspace(1)* {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
; CHECK-LLVM: [[PTR_i27_AS_CAST:[%0-9a-z.]+]] = addrspacecast i32 addrspace(1)* [[PTR_i27]] to i32 addrspace(4)*
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* [[PTR_i27_AS_CAST]], i8* getelementptr inbounds ({{.*}} [[PTR_i27_ANNOT_STR]]
; TODO: add check that load is called for result of ptr.annotation when corresponding bug is fixed
; CHECK-LLVM: [[PTR_RESULT_LOAD:[%0-9a-z.]+]] = load i32, i32 addrspace(4)* [[PTR_ANNOT_CALL]]
%add.ptr.i15.i = getelementptr inbounds i32, i32 addrspace(1)* %add.ptr.i27, i64 1
%7 = addrspacecast i32 addrspace(1)* %add.ptr.i15.i to i32 addrspace(4)*
%8 = tail call dereferenceable(4) i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %7, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i64 0, i64 0), i32 0) #2
%9 = load i32, i32 addrspace(4)* %8, align 4, !tbaa !9
; CHECK-LLVM: [[PTR_i15_i:[%0-9a-z.]+]] = getelementptr inbounds i32, i32 addrspace(1)* {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
; CHECK-LLVM: [[PTR_i15_i_AS_CAST:[%0-9a-z.]+]] = addrspacecast i32 addrspace(1)* [[PTR_i15_i]] to i32 addrspace(4)*
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* [[PTR_i15_i_AS_CAST]], i8* getelementptr inbounds ({{.*}} [[PTR_i15_i_ANNOT_STR]]
; TODO: add check that load is called for result of ptr.annotation when corresponding bug is fixed
; CHECK-LLVM: [[PTR_RESULT_LOAD_1:[%0-9a-z.]+]] = load i32, i32 addrspace(4)* [[PTR_ANNOT_CALL]]
%10 = addrspacecast i32 addrspace(1)* %add.ptr.i to i32 addrspace(4)*
%11 = tail call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %10, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i64 0, i64 0), i32 0) #2
store i32 %6, i32 addrspace(4)* %11, align 4, !tbaa !9
; CHECK-LLVM: [[PTR_i_AS_CAST:[%0-9a-z.]+]] = addrspacecast i32 addrspace(1)* [[PTR_i]] to i32 addrspace(4)*
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* [[PTR_i_AS_CAST]], i8* getelementptr inbounds ({{.*}} [[PTR_i_ANNOT_STR]]
; TODO: add check that store is called for result of ptr.annotation when corresponding bug is fixed
; CHECK-LLVM: store i32 [[PTR_RESULT_LOAD]], i32 addrspace(4)* [[PTR_ANNOT_CALL]]
%add.ptr.i.i = getelementptr inbounds i32, i32 addrspace(1)* %add.ptr.i, i64 1
%12 = addrspacecast i32 addrspace(1)* %add.ptr.i.i to i32 addrspace(4)*
%13 = tail call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* %12, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.1, i64 0, i64 0), i32 0) #2
store i32 %9, i32 addrspace(4)* %13, align 4, !tbaa !9
; CHECK-LLVM: [[PTR_i_i:[%0-9a-z.]+]] = getelementptr inbounds i32, i32 addrspace(1)* {{[%0-9a-z._]+}}, i64 {{[%0-9a-z.]+}}
; CHECK-LLVM: [[PTR_i_i_AS_CAST:[%0-9a-z.]+]] = addrspacecast i32 addrspace(1)* [[PTR_i_i]] to i32 addrspace(4)*
; CHECK-LLVM: [[PTR_ANNOT_CALL:[%0-9a-z.]+]] = call i32 addrspace(4)* @llvm.ptr.annotation.p4i32(i32 addrspace(4)* [[PTR_i_i_AS_CAST]], i8* getelementptr inbounds ({{.*}} [[PTR_i_i_ANNOT_STR]]
; TODO: add check that store is called for result of ptr.annotation when corresponding bug is fixed
; CHECK-LLVM: store i32 [[PTR_RESULT_LOAD_1]], i32 addrspace(4)* [[PTR_ANNOT_CALL]]
ret void
}

Expand Down

0 comments on commit 7c0f43c

Please sign in to comment.