Skip to content

Commit 14cf511

Browse files
vmaksimoDmitry Sidorov
andauthored
[Backport to 17] Enhance handling of umul_with_overflow in reverse translation (#3524)
Co-authored-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
1 parent b2c4d3a commit 14cf511

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

lib/SPIRV/SPIRVReader.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3420,6 +3420,20 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF, unsigned AS) {
34203420
{FT->getParamType(0), FT->getParamType(2)})
34213421
->getName();
34223422
}
3423+
3424+
// Special handling for spirv.llvm_umul_with_overflow_* functions
3425+
// These were created during forward translation by lowering intrinsics.
3426+
// During reverse translation, we replace them with intrinsic calls.
3427+
if (FuncNameRef.starts_with("spirv.llvm_umul_with_overflow_")) {
3428+
Type *OverloadTy = FT->getParamType(0);
3429+
Function *F = Intrinsic::getDeclaration(M, Intrinsic::umul_with_overflow,
3430+
{OverloadTy});
3431+
F = cast<Function>(mapValue(BF, F));
3432+
mapFunction(BF, F);
3433+
return F; // Skip body translation - intrinsic will be used instead
3434+
}
3435+
3436+
// Normal function handling.
34233437
if (FuncNameRef.consume_front("spirv.")) {
34243438
FuncNameRef.consume_back(".volatile");
34253439
FuncName = FuncNameRef.str();
@@ -3428,21 +3442,12 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF, unsigned AS) {
34283442
Function *F = M->getFunction(FuncName);
34293443
if (!F)
34303444
F = Function::Create(FT, Linkage, AS, FuncName, M);
3445+
34313446
F = cast<Function>(mapValue(BF, F));
34323447
mapFunction(BF, F);
34333448

34343449
if (F->isIntrinsic()) {
3435-
if (F->getIntrinsicID() != Intrinsic::umul_with_overflow)
3436-
return F;
3437-
std::string Name = F->getName().str();
3438-
auto *ST = cast<StructType>(F->getReturnType());
3439-
auto *FT = F->getFunctionType();
3440-
auto *NewST = StructType::get(ST->getContext(), ST->elements());
3441-
auto *NewFT = FunctionType::get(NewST, FT->params(), FT->isVarArg());
3442-
F->setName("old_" + Name);
3443-
auto *NewFn = Function::Create(NewFT, F->getLinkage(), F->getAddressSpace(),
3444-
Name, F->getParent());
3445-
return NewFn;
3450+
return F;
34463451
}
34473452

34483453
F->setCallingConv(IsKernel ? CallingConv::SPIR_KERNEL

test/llvm-intrinsics/umul.with.overflow.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
; On LLVM level, we'll check that the intrinsics were generated again in reverse
77
; translation, replacing the SPIR-V level implementations.
88
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM \
9-
; RUN: "--implicit-check-not=declare {{.*}} @spirv.llvm_umul_with_overflow_{{.*}}"
9+
; RUN: "--implicit-check-not=declare {{.*}} @spirv.llvm_umul_with_overflow_{{.*}}" \
10+
; RUN: "--implicit-check-not=old_llvm.umul.with.overflow.{{.*}}"
1011

1112
; CHECK-SPIRV: Name [[NAME_UMUL_FUNC_8:[0-9]+]] "spirv.llvm_umul_with_overflow_i8"
1213
; CHECK-SPIRV: Name [[NAME_UMUL_FUNC_32:[0-9]+]] "spirv.llvm_umul_with_overflow_i32"
@@ -25,6 +26,8 @@ entry:
2526
%umul.value = extractvalue { i8, i1 } %umul, 0
2627
%storemerge = select i1 %cmp, i8 0, i8 %umul.value
2728
store i8 %storemerge, i8* %c, align 1, !tbaa !2
29+
; This test case verifies we don't leave any artifact calls behind (e.g. old_llvm.umul.with.overflow.i8).
30+
%umul2 = tail call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
2831
ret void
2932
}
3033

0 commit comments

Comments
 (0)