Skip to content

Commit b959fa2

Browse files
github-actions[bot]vmaksimoDmitry Sidorov
authored
[Backport to llvm_release_190] Enhance handling of umul_with_overflow in reverse translation (#3522)
Backport of PR #3518 into `llvm_release_190`. All commits applied cleanly. --------- Co-authored-by: Viktoria Maximova <viktoria.maksimova@intel.com> Co-authored-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
1 parent abf16eb commit b959fa2

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
@@ -3439,6 +3439,20 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF, unsigned AS) {
34393439
{FT->getParamType(0), FT->getParamType(2)})
34403440
->getName();
34413441
}
3442+
3443+
// Special handling for spirv.llvm_umul_with_overflow_* functions
3444+
// These were created during forward translation by lowering intrinsics.
3445+
// During reverse translation, we replace them with intrinsic calls.
3446+
if (FuncNameRef.starts_with("spirv.llvm_umul_with_overflow_")) {
3447+
Type *OverloadTy = FT->getParamType(0);
3448+
Function *F = Intrinsic::getDeclaration(M, Intrinsic::umul_with_overflow,
3449+
{OverloadTy});
3450+
F = cast<Function>(mapValue(BF, F));
3451+
mapFunction(BF, F);
3452+
return F; // Skip body translation - intrinsic will be used instead
3453+
}
3454+
3455+
// Normal function handling.
34423456
if (FuncNameRef.consume_front("spirv.")) {
34433457
FuncNameRef.consume_back(".volatile");
34443458
FuncName = FuncNameRef.str();
@@ -3447,21 +3461,12 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF, unsigned AS) {
34473461
Function *F = M->getFunction(FuncName);
34483462
if (!F)
34493463
F = Function::Create(FT, Linkage, AS, FuncName, M);
3464+
34503465
F = cast<Function>(mapValue(BF, F));
34513466
mapFunction(BF, F);
34523467

34533468
if (F->isIntrinsic()) {
3454-
if (F->getIntrinsicID() != Intrinsic::umul_with_overflow)
3455-
return F;
3456-
std::string Name = F->getName().str();
3457-
auto *ST = cast<StructType>(F->getReturnType());
3458-
auto *FT = F->getFunctionType();
3459-
auto *NewST = StructType::get(ST->getContext(), ST->elements());
3460-
auto *NewFT = FunctionType::get(NewST, FT->params(), FT->isVarArg());
3461-
F->setName("old_" + Name);
3462-
auto *NewFn = Function::Create(NewFT, F->getLinkage(), F->getAddressSpace(),
3463-
Name, F->getParent());
3464-
return NewFn;
3469+
return F;
34653470
}
34663471

34673472
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, ptr %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)