From 6677b2f2f2e516e72752edf52465ff58df0bd6f2 Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Thu, 15 May 2025 23:29:07 +0100 Subject: [PATCH 01/13] Add pass which forwards unimplemented math builtins / libcalls to the HIPSTDPAR runtime component. --- .../llvm/Transforms/HipStdPar/HipStdPar.h | 7 + llvm/lib/Passes/PassRegistry.def | 1 + .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 8 +- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 117 +++++++++ llvm/test/Transforms/HipStdPar/math-fixup.ll | 240 ++++++++++++++++++ 5 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/HipStdPar/math-fixup.ll diff --git a/llvm/include/llvm/Transforms/HipStdPar/HipStdPar.h b/llvm/include/llvm/Transforms/HipStdPar/HipStdPar.h index 5ff38bdf04812..27195051ed7eb 100644 --- a/llvm/include/llvm/Transforms/HipStdPar/HipStdPar.h +++ b/llvm/include/llvm/Transforms/HipStdPar/HipStdPar.h @@ -40,6 +40,13 @@ class HipStdParAllocationInterpositionPass static bool isRequired() { return true; } }; +class HipStdParMathFixupPass : public PassInfoMixin { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + + static bool isRequired() { return true; } +}; + } // namespace llvm #endif // LLVM_TRANSFORMS_HIPSTDPAR_HIPSTDPAR_H diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 94dabe290213d..3acdbf4d49fde 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -80,6 +80,7 @@ MODULE_PASS("global-merge-func", GlobalMergeFuncPass()) MODULE_PASS("globalopt", GlobalOptPass()) MODULE_PASS("globalsplit", GlobalSplitPass()) MODULE_PASS("hipstdpar-interpose-alloc", HipStdParAllocationInterpositionPass()) +MODULE_PASS("hipstdpar-math-fixup", HipStdParMathFixupPass()) MODULE_PASS("hipstdpar-select-accelerator-code", HipStdParAcceleratorCodeSelectionPass()) MODULE_PASS("hotcoldsplit", HotColdSplittingPass()) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index ccb251b730f16..c3f8cee1e1783 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -819,8 +819,10 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { // When we are not using -fgpu-rdc, we can run accelerator code // selection relatively early, but still after linking to prevent // eager removal of potentially reachable symbols. - if (EnableHipStdPar) + if (EnableHipStdPar) { + PM.addPass(HipStdParMathFixupPass()); PM.addPass(HipStdParAcceleratorCodeSelectionPass()); + } PM.addPass(AMDGPUPrintfRuntimeBindingPass()); } @@ -899,8 +901,10 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { // selection after linking to prevent, otherwise we end up removing // potentially reachable symbols that were exported as external in other // modules. - if (EnableHipStdPar) + if (EnableHipStdPar) { + PM.addPass(HipStdParMathFixupPass()); PM.addPass(HipStdParAcceleratorCodeSelectionPass()); + } // We want to support the -lto-partitions=N option as "best effort". // For that, we need to lower LDS earlier in the pipeline before the // module is partitioned for codegen. diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index 5a87cf8c83d79..815878089c69e 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -37,6 +37,16 @@ // memory that ends up in one of the runtime equivalents, since this can // happen if e.g. a library that was compiled without interposition returns // an allocation that can be validly passed to `free`. +// +// 3. MathFixup (required): Some accelerators might have an incomplete +// implementation for the intrinsics used to implement some of the math +// functions in / their corresponding libcall lowerings. Since this +// can vary quite significantly between accelerators, we replace calls to a +// set of intrinsics / lib functions known to be problematic with calls to a +// HIPSTDPAR specific forwarding layer, which gives an uniform interface for +// accelerators to implement in their own runtime components. This pass +// should run before AcceleratorCodeSelection so as to prevent the spurious +// removal of the HIPSTDPAR specific forwarding functions. //===----------------------------------------------------------------------===// #include "llvm/Transforms/HipStdPar/HipStdPar.h" @@ -48,6 +58,7 @@ #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -321,3 +332,109 @@ HipStdParAllocationInterpositionPass::run(Module &M, ModuleAnalysisManager&) { return PreservedAnalyses::none(); } + +static constexpr std::pair MathLibToHipStdPar[]{ + {"acosh", "__hipstdpar_acosh_f64"}, + {"acoshf", "__hipstdpar_acosh_f32"}, + {"asinh", "__hipstdpar_asinh_f64"}, + {"asinhf", "__hipstdpar_asinh_f32"}, + {"atanh", "__hipstdpar_atanh_f64"}, + {"atanhf", "__hipstdpar_atanh_f32"}, + {"cbrt", "__hipstdpar_cbrt_f64"}, + {"cbrtf", "__hipstdpar_cbrt_f32"}, + {"erf", "__hipstdpar_erf_f64"}, + {"erff", "__hipstdpar_erf_f32"}, + {"erfc", "__hipstdpar_erfc_f64"}, + {"erfcf", "__hipstdpar_erfc_f32"}, + {"fdim", "__hipstdpar_fdim_f64"}, + {"fdimf", "__hipstdpar_fdim_f32"}, + {"expm1", "__hipstdpar_expm1_f64"}, + {"expm1f", "__hipstdpar_expm1_f32"}, + {"hypot", "__hipstdpar_hypot_f64"}, + {"hypotf", "__hipstdpar_hypot_f32"}, + {"ilogb", "__hipstdpar_ilogb_f64"}, + {"ilogbf", "__hipstdpar_ilogb_f32"}, + {"lgamma", "__hipstdpar_lgamma_f64"}, + {"lgammaf", "__hipstdpar_lgamma_f32"}, + {"log1p", "__hipstdpar_log1p_f64"}, + {"log1pf", "__hipstdpar_log1p_f32"}, + {"logb", "__hipstdpar_logb_f64"}, + {"logbf", "__hipstdpar_logb_f32"}, + {"nextafter", "__hipstdpar_nextafter_f64"}, + {"nextafterf", "__hipstdpar_nextafter_f32"}, + {"nexttoward", "__hipstdpar_nexttoward_f64"}, + {"nexttowardf", "__hipstdpar_nexttoward_f32"}, + {"remainder", "__hipstdpar_remainder_f64"}, + {"remainderf", "__hipstdpar_remainder_f32"}, + {"remquo", "__hipstdpar_remquo_f64"}, + {"remquof", "__hipstdpar_remquo_f32"}, + {"scalbln", "__hipstdpar_scalbln_f64"}, + {"scalblnf", "__hipstdpar_scalbln_f32"}, + {"scalbn", "__hipstdpar_scalbn_f64"}, + {"scalbnf", "__hipstdpar_scalbn_f32"}, + {"tgamma", "__hipstdpar_tgamma_f64"}, + {"tgammaf", "__hipstdpar_tgamma_f32"}}; + +PreservedAnalyses HipStdParMathFixupPass::run(Module &M, + ModuleAnalysisManager &) { + if (M.empty()) + return PreservedAnalyses::all(); + + SmallVector> ToReplace; + for (auto &&F : M) { + if (!F.hasName()) + continue; + + auto N = F.getName().str(); + auto ID = F.getIntrinsicID(); + + switch (ID) { + case Intrinsic::not_intrinsic: { + auto It = find_if(MathLibToHipStdPar, + [&](auto &&M) { return M.first == N; }); + if (It == std::cend(MathLibToHipStdPar)) + continue; + ToReplace.emplace_back(&F, It->second); + break; + } + case Intrinsic::acos: + case Intrinsic::asin: + case Intrinsic::atan: + case Intrinsic::atan2: + case Intrinsic::cosh: + case Intrinsic::modf: + case Intrinsic::sinh: + case Intrinsic::tan: + case Intrinsic::tanh: + break; + default: { + if (F.getReturnType()->isDoubleTy()) { + switch (ID) { + case Intrinsic::cos: + case Intrinsic::exp: + case Intrinsic::exp2: + case Intrinsic::log: + case Intrinsic::log10: + case Intrinsic::log2: + case Intrinsic::pow: + case Intrinsic::sin: + break; + default: + continue; + } + break; + } + continue; + } + } + + llvm::replace(N, '.', '_'); + N.replace(0, sizeof("llvm"), "__hipstdpar_"); + ToReplace.emplace_back(&F, std::move(N)); + } + for (auto &&F : ToReplace) + F.first->replaceAllUsesWith(M.getOrInsertFunction( + F.second, F.first->getFunctionType()).getCallee()); + + return PreservedAnalyses::none(); +} \ No newline at end of file diff --git a/llvm/test/Transforms/HipStdPar/math-fixup.ll b/llvm/test/Transforms/HipStdPar/math-fixup.ll new file mode 100644 index 0000000000000..e0e2ca79c0843 --- /dev/null +++ b/llvm/test/Transforms/HipStdPar/math-fixup.ll @@ -0,0 +1,240 @@ +; RUN: opt -S -passes=hipstdpar-math-fixup %s | FileCheck %s + +define void @foo(double noundef %dbl, float noundef %flt, i32 noundef %quo) #0 { +; CHECK-LABEL: define void @foo( +; CHECK-SAME: double noundef [[DBL:%.*]], float noundef [[FLT:%.*]], i32 noundef [[QUO:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[QUO_ADDR:%.*]] = alloca i32, align 4 +; CHECK-NEXT: store i32 [[QUO]], ptr [[QUO_ADDR]], align 4 +entry: + %quo.addr = alloca i32, align 4 + store i32 %quo, ptr %quo.addr, align 4 + ; CHECK-NEXT: [[TMP0:%.*]] = tail call contract double @llvm.fabs.f64(double [[DBL]]) + %0 = tail call contract double @llvm.fabs.f64(double %dbl) + ; CHECK-NEXT: [[TMP1:%.*]] = tail call contract float @llvm.fabs.f32(float [[FLT]]) + %1 = tail call contract float @llvm.fabs.f32(float %flt) + ; CHECK-NEXT: [[CALL:%.*]] = tail call contract double @__hipstdpar_remainder_f64(double noundef [[TMP0]], double noundef [[TMP0]]) #[[ATTR4:[0-9]+]] + %call = tail call contract double @remainder(double noundef %0, double noundef %0) #4 + ; CHECK-NEXT: [[CALL1:%.*]] = tail call contract float @__hipstdpar_remainder_f32(float noundef [[TMP1]], float noundef [[TMP1]]) #[[ATTR4]] + %call1 = tail call contract float @remainderf(float noundef %1, float noundef %1) #4 + ; CHECK-NEXT: [[CALL2:%.*]] = call contract double @__hipstdpar_remquo_f64(double noundef [[CALL]], double noundef [[CALL]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3:[0-9]+]] + %call2 = call contract double @remquo(double noundef %call, double noundef %call, ptr noundef nonnull %quo.addr) #5 + ; CHECK-NEXT: [[CALL3:%.*]] = call contract float @__hipstdpar_remquo_f32(float noundef [[CALL1]], float noundef [[CALL1]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3]] + %call3 = call contract float @remquof(float noundef %call1, float noundef %call1, ptr noundef nonnull %quo.addr) #5 + ; CHECK-NEXT: [[TMP2:%.*]] = call contract double @llvm.fma.f64(double [[CALL2]], double [[CALL2]], double [[CALL2]]) + %2 = call contract double @llvm.fma.f64(double %call2, double %call2, double %call2) + ; CHECK-NEXT: [[TMP3:%.*]] = call contract float @llvm.fma.f32(float [[CALL3]], float [[CALL3]], float [[CALL3]]) + %3 = call contract float @llvm.fma.f32(float %call3, float %call3, float %call3) + ; CHECK-NEXT: [[CALL4:%.*]] = call contract double @__hipstdpar_fdim_f64(double noundef [[TMP2]], double noundef [[TMP2]]) #[[ATTR4]] + %call4 = call contract double @fdim(double noundef %2, double noundef %2) #4 + ; CHECK-NEXT: [[CALL5:%.*]] = call contract float @__hipstdpar_fdim_f32(float noundef [[TMP3]], float noundef [[TMP3]]) #[[ATTR4]] + %call5 = call contract float @fdimf(float noundef %3, float noundef %3) #4 + ; CHECK-NEXT: [[TMP4:%.*]] = call contract double @__hipstdpar_exp_f64(double [[CALL4]]) + %4 = call contract double @llvm.exp.f64(double %call4) + ; CHECK-NEXT: [[TMP5:%.*]] = call contract float @llvm.exp.f32(float [[CALL5]]) + %5 = call contract float @llvm.exp.f32(float %call5) + ; CHECK-NEXT: [[TMP6:%.*]] = call contract double @__hipstdpar_exp2_f64(double [[TMP4]]) + %6 = call contract double @llvm.exp2.f64(double %4) + ; CHECK-NEXT: [[TMP7:%.*]] = call contract float @llvm.exp2.f32(float [[TMP5]]) + %7 = call contract float @llvm.exp2.f32(float %5) + ; CHECK-NEXT: [[CALL6:%.*]] = call contract double @__hipstdpar_expm1_f64(double noundef [[TMP6]]) #[[ATTR4]] + %call6 = call contract double @expm1(double noundef %6) #4 + ; CHECK-NEXT: [[CALL7:%.*]] = call contract float @__hipstdpar_expm1_f32(float noundef [[TMP7]]) #[[ATTR4]] + %call7 = call contract float @expm1f(float noundef %7) #4 + ; CHECK-NEXT: [[TMP8:%.*]] = call contract double @__hipstdpar_log_f64(double [[CALL6]]) + %8 = call contract double @llvm.log.f64(double %call6) + ; CHECK-NEXT: [[TMP9:%.*]] = call contract float @llvm.log.f32(float [[CALL7]]) + %9 = call contract float @llvm.log.f32(float %call7) + ; CHECK-NEXT: [[TMP10:%.*]] = call contract double @__hipstdpar_log10_f64(double [[TMP8]]) + %10 = call contract double @llvm.log10.f64(double %8) + ; CHECK-NEXT: [[TMP11:%.*]] = call contract float @llvm.log10.f32(float [[TMP9]]) + %11 = call contract float @llvm.log10.f32(float %9) + ; CHECK-NEXT: [[TMP12:%.*]] = call contract double @__hipstdpar_log2_f64(double [[TMP10]]) + %12 = call contract double @llvm.log2.f64(double %10) + ; CHECK-NEXT: [[TMP13:%.*]] = call contract float @llvm.log2.f32(float [[TMP11]]) + %13 = call contract float @llvm.log2.f32(float %11) + ; CHECK-NEXT: [[CALL8:%.*]] = call contract double @__hipstdpar_log1p_f64(double noundef [[TMP12]]) #[[ATTR4]] + %call8 = call contract double @log1p(double noundef %12) #4 + ; CHECK-NEXT: [[CALL9:%.*]] = call contract float @__hipstdpar_log1p_f32(float noundef [[TMP13]]) #[[ATTR4]] + %call9 = call contract float @log1pf(float noundef %13) #4 + ; CHECK-NEXT: [[TMP14:%.*]] = call contract float @llvm.pow.f32(float [[CALL9]], float [[CALL9]]) + %14 = call contract float @llvm.pow.f32(float %call9, float %call9) + ; CHECK-NEXT: [[TMP15:%.*]] = call contract double @llvm.sqrt.f64(double [[CALL8]]) + %15 = call contract double @llvm.sqrt.f64(double %call8) + ; CHECK-NEXT: [[TMP16:%.*]] = call contract float @llvm.sqrt.f32(float [[TMP14]]) + %16 = call contract float @llvm.sqrt.f32(float %14) + ; CHECK-NEXT: [[CALL10:%.*]] = call contract double @__hipstdpar_cbrt_f64(double noundef [[TMP15]]) #[[ATTR4]] + %call10 = call contract double @cbrt(double noundef %15) #4 + ; CHECK-NEXT: [[CALL11:%.*]] = call contract float @__hipstdpar_cbrt_f32(float noundef [[TMP16]]) #[[ATTR4]] + %call11 = call contract float @cbrtf(float noundef %16) #4 + ; CHECK-NEXT: [[CALL12:%.*]] = call contract double @__hipstdpar_hypot_f64(double noundef [[CALL10]], double noundef [[CALL10]]) #[[ATTR4]] + %call12 = call contract double @hypot(double noundef %call10, double noundef %call10) #4 + ; CHECK-NEXT: [[CALL13:%.*]] = call contract float @__hipstdpar_hypot_f32(float noundef [[CALL11]], float noundef [[CALL11]]) #[[ATTR4]] + %call13 = call contract float @hypotf(float noundef %call11, float noundef %call11) #4 + ; CHECK-NEXT: [[TMP17:%.*]] = call contract float @llvm.sin.f32(float [[CALL13]]) + %17 = call contract float @llvm.sin.f32(float %call13) + ; CHECK-NEXT: [[TMP18:%.*]] = call contract float @llvm.cos.f32(float [[TMP17]]) + %18 = call contract float @llvm.cos.f32(float %17) + ; CHECK-NEXT: [[TMP19:%.*]] = call contract double @__hipstdpar_tan_f64(double [[CALL12]]) + %19 = call contract double @llvm.tan.f64(double %call12) + ; CHECK-NEXT: [[TMP20:%.*]] = call contract double @__hipstdpar_asin_f64(double [[TMP19]]) + %20 = call contract double @llvm.asin.f64(double %19) + ; CHECK-NEXT: [[TMP21:%.*]] = call contract double @__hipstdpar_acos_f64(double [[TMP20]]) + %21 = call contract double @llvm.acos.f64(double %20) + ; CHECK-NEXT: [[TMP22:%.*]] = call contract double @__hipstdpar_atan_f64(double [[TMP21]]) + %22 = call contract double @llvm.atan.f64(double %21) + ; CHECK-NEXT: [[TMP23:%.*]] = call contract double @__hipstdpar_atan2_f64(double [[TMP22]], double [[TMP22]]) + %23 = call contract double @llvm.atan2.f64(double %22, double %22) + ; CHECK-NEXT: [[TMP24:%.*]] = call contract double @__hipstdpar_sinh_f64(double [[TMP23]]) + %24 = call contract double @llvm.sinh.f64(double %23) + ; CHECK-NEXT: [[TMP25:%.*]] = call contract double @__hipstdpar_cosh_f64(double [[TMP24]]) + %25 = call contract double @llvm.cosh.f64(double %24) + ; CHECK-NEXT: [[TMP26:%.*]] = call contract double @__hipstdpar_tanh_f64(double [[TMP25]]) + %26 = call contract double @llvm.tanh.f64(double %25) + ; CHECK-NEXT: [[CALL14:%.*]] = call contract double @__hipstdpar_asinh_f64(double noundef [[TMP26]]) #[[ATTR4]] + %call14 = call contract double @asinh(double noundef %26) #4 + ; CHECK-NEXT: [[CALL15:%.*]] = call contract float @__hipstdpar_asinh_f32(float noundef [[TMP18]]) #[[ATTR4]] + %call15 = call contract float @asinhf(float noundef %18) #4 + ; CHECK-NEXT: [[CALL16:%.*]] = call contract double @__hipstdpar_acosh_f64(double noundef [[CALL14]]) #[[ATTR4]] + %call16 = call contract double @acosh(double noundef %call14) #4 + ; CHECK-NEXT: [[CALL17:%.*]] = call contract float @__hipstdpar_acosh_f32(float noundef [[CALL15]]) #[[ATTR4]] + %call17 = call contract float @acoshf(float noundef %call15) #4 + ; CHECK-NEXT: [[CALL18:%.*]] = call contract double @__hipstdpar_atanh_f64(double noundef [[CALL16]]) #[[ATTR4]] + %call18 = call contract double @atanh(double noundef %call16) #4 + ; CHECK-NEXT: [[CALL19:%.*]] = call contract float @__hipstdpar_atanh_f32(float noundef [[CALL17]]) #[[ATTR4]] + %call19 = call contract float @atanhf(float noundef %call17) #4 + ; CHECK-NEXT: [[CALL20:%.*]] = call contract double @__hipstdpar_erf_f64(double noundef [[CALL18]]) #[[ATTR4]] + %call20 = call contract double @erf(double noundef %call18) #4 + ; CHECK-NEXT: [[CALL21:%.*]] = call contract float @__hipstdpar_erf_f32(float noundef [[CALL19]]) #[[ATTR4]] + %call21 = call contract float @erff(float noundef %call19) #4 + ; CHECK-NEXT: [[CALL22:%.*]] = call contract double @__hipstdpar_erfc_f64(double noundef [[CALL20]]) #[[ATTR4]] + %call22 = call contract double @erfc(double noundef %call20) #4 + ; CHECK-NEXT: [[CALL23:%.*]] = call contract float @__hipstdpar_erfc_f32(float noundef [[CALL21]]) #[[ATTR4]] + %call23 = call contract float @erfcf(float noundef %call21) #4 + ; CHECK-NEXT: [[CALL24:%.*]] = call contract double @__hipstdpar_tgamma_f64(double noundef [[CALL22]]) #[[ATTR4]] + %call24 = call contract double @tgamma(double noundef %call22) #4 + ; CHECK-NEXT: [[CALL25:%.*]] = call contract float @__hipstdpar_tgamma_f32(float noundef [[CALL23]]) #[[ATTR4]] + %call25 = call contract float @tgammaf(float noundef %call23) #4 + ; CHECK-NEXT: [[CALL26:%.*]] = call contract double @__hipstdpar_lgamma_f64(double noundef [[CALL24]]) #[[ATTR3]] + %call26 = call contract double @lgamma(double noundef %call24) #5 + ; CHECK-NEXT: [[CALL27:%.*]] = call contract float @__hipstdpar_lgamma_f32(float noundef [[CALL25]]) #[[ATTR3]] + %call27 = call contract float @lgammaf(float noundef %call25) #5 + ret void +} + +declare double @llvm.fabs.f64(double) #1 + +declare float @llvm.fabs.f32(float) #1 + +declare hidden double @remainder(double noundef, double noundef) local_unnamed_addr #2 + +declare hidden float @remainderf(float noundef, float noundef) local_unnamed_addr #2 + +declare hidden double @remquo(double noundef, double noundef, ptr noundef) local_unnamed_addr #3 + +declare hidden float @remquof(float noundef, float noundef, ptr noundef) local_unnamed_addr #3 + +declare double @llvm.fma.f64(double, double, double) #1 + +declare float @llvm.fma.f32(float, float, float) #1 + +declare hidden double @fdim(double noundef, double noundef) local_unnamed_addr #2 + +declare hidden float @fdimf(float noundef, float noundef) local_unnamed_addr #2 + +declare double @llvm.exp.f64(double) #1 + +declare float @llvm.exp.f32(float) #1 + +declare double @llvm.exp2.f64(double) #1 + +declare float @llvm.exp2.f32(float) #1 + +declare hidden double @expm1(double noundef) local_unnamed_addr #2 + +declare hidden float @expm1f(float noundef) local_unnamed_addr #2 + +declare double @llvm.log.f64(double) #1 + +declare float @llvm.log.f32(float) #1 + +declare double @llvm.log10.f64(double) #1 + +declare float @llvm.log10.f32(float) #1 + +declare double @llvm.log2.f64(double) #1 + +declare float @llvm.log2.f32(float) #1 + +declare hidden double @log1p(double noundef) local_unnamed_addr #2 + +declare hidden float @log1pf(float noundef) local_unnamed_addr #2 + +declare float @llvm.pow.f32(float, float) #1 + +declare double @llvm.sqrt.f64(double) #1 + +declare float @llvm.sqrt.f32(float) #1 + +declare hidden double @cbrt(double noundef) local_unnamed_addr #2 + +declare hidden float @cbrtf(float noundef) local_unnamed_addr #2 + +declare hidden double @hypot(double noundef, double noundef) local_unnamed_addr #2 + +declare hidden float @hypotf(float noundef, float noundef) local_unnamed_addr #2 + +declare float @llvm.sin.f32(float) #1 + +declare float @llvm.cos.f32(float) #1 + +declare double @llvm.tan.f64(double) #1 + +declare double @llvm.asin.f64(double) #1 + +declare double @llvm.acos.f64(double) #1 + +declare double @llvm.atan.f64(double) #1 + +declare double @llvm.atan2.f64(double, double) #1 + +declare double @llvm.sinh.f64(double) #1 + +declare double @llvm.cosh.f64(double) #1 + +declare double @llvm.tanh.f64(double) #1 + +declare hidden double @asinh(double noundef) local_unnamed_addr #2 + +declare hidden float @asinhf(float noundef) local_unnamed_addr #2 + +declare hidden double @acosh(double noundef) local_unnamed_addr #2 + +declare hidden float @acoshf(float noundef) local_unnamed_addr #2 + +declare hidden double @atanh(double noundef) local_unnamed_addr #2 + +declare hidden float @atanhf(float noundef) local_unnamed_addr #2 + +declare hidden double @erf(double noundef) local_unnamed_addr #2 + +declare hidden float @erff(float noundef) local_unnamed_addr #2 + +declare hidden double @erfc(double noundef) local_unnamed_addr #2 + +declare hidden float @erfcf(float noundef) local_unnamed_addr #2 + +declare hidden double @tgamma(double noundef) local_unnamed_addr #2 + +declare hidden float @tgammaf(float noundef) local_unnamed_addr #2 + +declare hidden double @lgamma(double noundef) local_unnamed_addr #3 + +declare hidden float @lgammaf(float noundef) local_unnamed_addr #3 + +attributes #0 = { convergent mustprogress norecurse nounwind } +attributes #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #2 = { convergent mustprogress nofree nounwind willreturn memory(none) } +attributes #3 = { convergent nounwind } +attributes #4 = { convergent nounwind willreturn memory(none) } +attributes #5 = { convergent nounwind } From a341315aa4991190354ac0e3d128dbe389700e9a Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Fri, 16 May 2025 00:08:11 +0100 Subject: [PATCH 02/13] Fix formatting. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index 815878089c69e..a5db4a6d160d8 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -390,8 +390,8 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, switch (ID) { case Intrinsic::not_intrinsic: { - auto It = find_if(MathLibToHipStdPar, - [&](auto &&M) { return M.first == N; }); + auto It = + find_if(MathLibToHipStdPar, [&](auto &&M) { return M.first == N; }); if (It == std::cend(MathLibToHipStdPar)) continue; ToReplace.emplace_back(&F, It->second); @@ -433,8 +433,9 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, ToReplace.emplace_back(&F, std::move(N)); } for (auto &&F : ToReplace) - F.first->replaceAllUsesWith(M.getOrInsertFunction( - F.second, F.first->getFunctionType()).getCallee()); + F.first->replaceAllUsesWith( + M.getOrInsertFunction(F.second, F.first->getFunctionType()) + .getCallee()); return PreservedAnalyses::none(); } \ No newline at end of file From a833e957c89909c806a9f5a662a657866cd84e38 Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Fri, 16 May 2025 01:30:35 +0100 Subject: [PATCH 03/13] Add missing whitespace. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index a5db4a6d160d8..e2150ed06e569 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -438,4 +438,4 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, .getCallee()); return PreservedAnalyses::none(); -} \ No newline at end of file +} From 057a86ab78c5dc04f08a1fa05fd2d4f44500e7bd Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Fri, 16 May 2025 20:12:28 +0100 Subject: [PATCH 04/13] Less `auto`. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index e2150ed06e569..30a0edad6c69a 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -385,8 +385,8 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, if (!F.hasName()) continue; - auto N = F.getName().str(); - auto ID = F.getIntrinsicID(); + StringRef N = F.getName(); + Intrinsic::ID ID = F.getIntrinsicID(); switch (ID) { case Intrinsic::not_intrinsic: { @@ -428,9 +428,9 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, } } - llvm::replace(N, '.', '_'); - N.replace(0, sizeof("llvm"), "__hipstdpar_"); ToReplace.emplace_back(&F, std::move(N)); + llvm::replace(ToReplace.back().second, '.', '_'); + ToReplace.back().second.replace(0, sizeof("llvm"), "__hipstdpar_"); } for (auto &&F : ToReplace) F.first->replaceAllUsesWith( From c59893815be8aadf1fb4bb49d53070e58582ab3d Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Tue, 20 May 2025 03:40:01 +0300 Subject: [PATCH 05/13] Auto-generate test. --- llvm/test/Transforms/HipStdPar/math-fixup.ll | 113 ++++++++++--------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/llvm/test/Transforms/HipStdPar/math-fixup.ll b/llvm/test/Transforms/HipStdPar/math-fixup.ll index e0e2ca79c0843..819f33a2e96f8 100644 --- a/llvm/test/Transforms/HipStdPar/math-fixup.ll +++ b/llvm/test/Transforms/HipStdPar/math-fixup.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S -passes=hipstdpar-math-fixup %s | FileCheck %s define void @foo(double noundef %dbl, float noundef %flt, i32 noundef %quo) #0 { @@ -6,118 +7,120 @@ define void @foo(double noundef %dbl, float noundef %flt, i32 noundef %quo) #0 { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[QUO_ADDR:%.*]] = alloca i32, align 4 ; CHECK-NEXT: store i32 [[QUO]], ptr [[QUO_ADDR]], align 4 +; CHECK-NEXT: [[TMP0:%.*]] = tail call contract double @llvm.fabs.f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call contract float @llvm.fabs.f32(float [[FLT]]) +; CHECK-NEXT: [[CALL:%.*]] = tail call contract double @__hipstdpar_remainder_f64(double noundef [[TMP0]], double noundef [[TMP0]]) #[[ATTR4:[0-9]+]] +; CHECK-NEXT: [[CALL1:%.*]] = tail call contract float @__hipstdpar_remainder_f32(float noundef [[TMP1]], float noundef [[TMP1]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL2:%.*]] = call contract double @__hipstdpar_remquo_f64(double noundef [[CALL]], double noundef [[CALL]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3:[0-9]+]] +; CHECK-NEXT: [[CALL3:%.*]] = call contract float @__hipstdpar_remquo_f32(float noundef [[CALL1]], float noundef [[CALL1]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3]] +; CHECK-NEXT: [[TMP2:%.*]] = call contract double @llvm.fma.f64(double [[CALL2]], double [[CALL2]], double [[CALL2]]) +; CHECK-NEXT: [[TMP3:%.*]] = call contract float @llvm.fma.f32(float [[CALL3]], float [[CALL3]], float [[CALL3]]) +; CHECK-NEXT: [[CALL4:%.*]] = call contract double @__hipstdpar_fdim_f64(double noundef [[TMP2]], double noundef [[TMP2]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL5:%.*]] = call contract float @__hipstdpar_fdim_f32(float noundef [[TMP3]], float noundef [[TMP3]]) #[[ATTR4]] +; CHECK-NEXT: [[TMP4:%.*]] = call contract double @__hipstdpar_exp_f64(double [[CALL4]]) +; CHECK-NEXT: [[TMP5:%.*]] = call contract float @llvm.exp.f32(float [[CALL5]]) +; CHECK-NEXT: [[TMP6:%.*]] = call contract double @__hipstdpar_exp2_f64(double [[TMP4]]) +; CHECK-NEXT: [[TMP7:%.*]] = call contract float @llvm.exp2.f32(float [[TMP5]]) +; CHECK-NEXT: [[CALL6:%.*]] = call contract double @__hipstdpar_expm1_f64(double noundef [[TMP6]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL7:%.*]] = call contract float @__hipstdpar_expm1_f32(float noundef [[TMP7]]) #[[ATTR4]] +; CHECK-NEXT: [[TMP8:%.*]] = call contract double @__hipstdpar_log_f64(double [[CALL6]]) +; CHECK-NEXT: [[TMP9:%.*]] = call contract float @llvm.log.f32(float [[CALL7]]) +; CHECK-NEXT: [[TMP10:%.*]] = call contract double @__hipstdpar_log10_f64(double [[TMP8]]) +; CHECK-NEXT: [[TMP11:%.*]] = call contract float @llvm.log10.f32(float [[TMP9]]) +; CHECK-NEXT: [[TMP12:%.*]] = call contract double @__hipstdpar_log2_f64(double [[TMP10]]) +; CHECK-NEXT: [[TMP13:%.*]] = call contract float @llvm.log2.f32(float [[TMP11]]) +; CHECK-NEXT: [[CALL8:%.*]] = call contract double @__hipstdpar_log1p_f64(double noundef [[TMP12]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL9:%.*]] = call contract float @__hipstdpar_log1p_f32(float noundef [[TMP13]]) #[[ATTR4]] +; CHECK-NEXT: [[TMP14:%.*]] = call contract float @llvm.pow.f32(float [[CALL9]], float [[CALL9]]) +; CHECK-NEXT: [[TMP15:%.*]] = call contract double @llvm.sqrt.f64(double [[CALL8]]) +; CHECK-NEXT: [[TMP16:%.*]] = call contract float @llvm.sqrt.f32(float [[TMP14]]) +; CHECK-NEXT: [[CALL10:%.*]] = call contract double @__hipstdpar_cbrt_f64(double noundef [[TMP15]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL11:%.*]] = call contract float @__hipstdpar_cbrt_f32(float noundef [[TMP16]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL12:%.*]] = call contract double @__hipstdpar_hypot_f64(double noundef [[CALL10]], double noundef [[CALL10]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL13:%.*]] = call contract float @__hipstdpar_hypot_f32(float noundef [[CALL11]], float noundef [[CALL11]]) #[[ATTR4]] +; CHECK-NEXT: [[TMP17:%.*]] = call contract float @llvm.sin.f32(float [[CALL13]]) +; CHECK-NEXT: [[TMP18:%.*]] = call contract float @llvm.cos.f32(float [[TMP17]]) +; CHECK-NEXT: [[TMP19:%.*]] = call contract double @__hipstdpar_tan_f64(double [[CALL12]]) +; CHECK-NEXT: [[TMP20:%.*]] = call contract double @__hipstdpar_asin_f64(double [[TMP19]]) +; CHECK-NEXT: [[TMP21:%.*]] = call contract double @__hipstdpar_acos_f64(double [[TMP20]]) +; CHECK-NEXT: [[TMP22:%.*]] = call contract double @__hipstdpar_atan_f64(double [[TMP21]]) +; CHECK-NEXT: [[TMP23:%.*]] = call contract double @__hipstdpar_atan2_f64(double [[TMP22]], double [[TMP22]]) +; CHECK-NEXT: [[TMP24:%.*]] = call contract double @__hipstdpar_sinh_f64(double [[TMP23]]) +; CHECK-NEXT: [[TMP25:%.*]] = call contract double @__hipstdpar_cosh_f64(double [[TMP24]]) +; CHECK-NEXT: [[TMP26:%.*]] = call contract double @__hipstdpar_tanh_f64(double [[TMP25]]) +; CHECK-NEXT: [[CALL14:%.*]] = call contract double @__hipstdpar_asinh_f64(double noundef [[TMP26]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL15:%.*]] = call contract float @__hipstdpar_asinh_f32(float noundef [[TMP18]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL16:%.*]] = call contract double @__hipstdpar_acosh_f64(double noundef [[CALL14]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL17:%.*]] = call contract float @__hipstdpar_acosh_f32(float noundef [[CALL15]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL18:%.*]] = call contract double @__hipstdpar_atanh_f64(double noundef [[CALL16]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL19:%.*]] = call contract float @__hipstdpar_atanh_f32(float noundef [[CALL17]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL20:%.*]] = call contract double @__hipstdpar_erf_f64(double noundef [[CALL18]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL21:%.*]] = call contract float @__hipstdpar_erf_f32(float noundef [[CALL19]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL22:%.*]] = call contract double @__hipstdpar_erfc_f64(double noundef [[CALL20]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL23:%.*]] = call contract float @__hipstdpar_erfc_f32(float noundef [[CALL21]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL24:%.*]] = call contract double @__hipstdpar_tgamma_f64(double noundef [[CALL22]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL25:%.*]] = call contract float @__hipstdpar_tgamma_f32(float noundef [[CALL23]]) #[[ATTR4]] +; CHECK-NEXT: [[CALL26:%.*]] = call contract double @__hipstdpar_lgamma_f64(double noundef [[CALL24]]) #[[ATTR3]] +; CHECK-NEXT: [[CALL27:%.*]] = call contract float @__hipstdpar_lgamma_f32(float noundef [[CALL25]]) #[[ATTR3]] +; CHECK-NEXT: ret void +; entry: %quo.addr = alloca i32, align 4 store i32 %quo, ptr %quo.addr, align 4 - ; CHECK-NEXT: [[TMP0:%.*]] = tail call contract double @llvm.fabs.f64(double [[DBL]]) %0 = tail call contract double @llvm.fabs.f64(double %dbl) - ; CHECK-NEXT: [[TMP1:%.*]] = tail call contract float @llvm.fabs.f32(float [[FLT]]) %1 = tail call contract float @llvm.fabs.f32(float %flt) - ; CHECK-NEXT: [[CALL:%.*]] = tail call contract double @__hipstdpar_remainder_f64(double noundef [[TMP0]], double noundef [[TMP0]]) #[[ATTR4:[0-9]+]] %call = tail call contract double @remainder(double noundef %0, double noundef %0) #4 - ; CHECK-NEXT: [[CALL1:%.*]] = tail call contract float @__hipstdpar_remainder_f32(float noundef [[TMP1]], float noundef [[TMP1]]) #[[ATTR4]] %call1 = tail call contract float @remainderf(float noundef %1, float noundef %1) #4 - ; CHECK-NEXT: [[CALL2:%.*]] = call contract double @__hipstdpar_remquo_f64(double noundef [[CALL]], double noundef [[CALL]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3:[0-9]+]] %call2 = call contract double @remquo(double noundef %call, double noundef %call, ptr noundef nonnull %quo.addr) #5 - ; CHECK-NEXT: [[CALL3:%.*]] = call contract float @__hipstdpar_remquo_f32(float noundef [[CALL1]], float noundef [[CALL1]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3]] %call3 = call contract float @remquof(float noundef %call1, float noundef %call1, ptr noundef nonnull %quo.addr) #5 - ; CHECK-NEXT: [[TMP2:%.*]] = call contract double @llvm.fma.f64(double [[CALL2]], double [[CALL2]], double [[CALL2]]) %2 = call contract double @llvm.fma.f64(double %call2, double %call2, double %call2) - ; CHECK-NEXT: [[TMP3:%.*]] = call contract float @llvm.fma.f32(float [[CALL3]], float [[CALL3]], float [[CALL3]]) %3 = call contract float @llvm.fma.f32(float %call3, float %call3, float %call3) - ; CHECK-NEXT: [[CALL4:%.*]] = call contract double @__hipstdpar_fdim_f64(double noundef [[TMP2]], double noundef [[TMP2]]) #[[ATTR4]] %call4 = call contract double @fdim(double noundef %2, double noundef %2) #4 - ; CHECK-NEXT: [[CALL5:%.*]] = call contract float @__hipstdpar_fdim_f32(float noundef [[TMP3]], float noundef [[TMP3]]) #[[ATTR4]] %call5 = call contract float @fdimf(float noundef %3, float noundef %3) #4 - ; CHECK-NEXT: [[TMP4:%.*]] = call contract double @__hipstdpar_exp_f64(double [[CALL4]]) %4 = call contract double @llvm.exp.f64(double %call4) - ; CHECK-NEXT: [[TMP5:%.*]] = call contract float @llvm.exp.f32(float [[CALL5]]) %5 = call contract float @llvm.exp.f32(float %call5) - ; CHECK-NEXT: [[TMP6:%.*]] = call contract double @__hipstdpar_exp2_f64(double [[TMP4]]) %6 = call contract double @llvm.exp2.f64(double %4) - ; CHECK-NEXT: [[TMP7:%.*]] = call contract float @llvm.exp2.f32(float [[TMP5]]) %7 = call contract float @llvm.exp2.f32(float %5) - ; CHECK-NEXT: [[CALL6:%.*]] = call contract double @__hipstdpar_expm1_f64(double noundef [[TMP6]]) #[[ATTR4]] %call6 = call contract double @expm1(double noundef %6) #4 - ; CHECK-NEXT: [[CALL7:%.*]] = call contract float @__hipstdpar_expm1_f32(float noundef [[TMP7]]) #[[ATTR4]] %call7 = call contract float @expm1f(float noundef %7) #4 - ; CHECK-NEXT: [[TMP8:%.*]] = call contract double @__hipstdpar_log_f64(double [[CALL6]]) %8 = call contract double @llvm.log.f64(double %call6) - ; CHECK-NEXT: [[TMP9:%.*]] = call contract float @llvm.log.f32(float [[CALL7]]) %9 = call contract float @llvm.log.f32(float %call7) - ; CHECK-NEXT: [[TMP10:%.*]] = call contract double @__hipstdpar_log10_f64(double [[TMP8]]) %10 = call contract double @llvm.log10.f64(double %8) - ; CHECK-NEXT: [[TMP11:%.*]] = call contract float @llvm.log10.f32(float [[TMP9]]) %11 = call contract float @llvm.log10.f32(float %9) - ; CHECK-NEXT: [[TMP12:%.*]] = call contract double @__hipstdpar_log2_f64(double [[TMP10]]) %12 = call contract double @llvm.log2.f64(double %10) - ; CHECK-NEXT: [[TMP13:%.*]] = call contract float @llvm.log2.f32(float [[TMP11]]) %13 = call contract float @llvm.log2.f32(float %11) - ; CHECK-NEXT: [[CALL8:%.*]] = call contract double @__hipstdpar_log1p_f64(double noundef [[TMP12]]) #[[ATTR4]] %call8 = call contract double @log1p(double noundef %12) #4 - ; CHECK-NEXT: [[CALL9:%.*]] = call contract float @__hipstdpar_log1p_f32(float noundef [[TMP13]]) #[[ATTR4]] %call9 = call contract float @log1pf(float noundef %13) #4 - ; CHECK-NEXT: [[TMP14:%.*]] = call contract float @llvm.pow.f32(float [[CALL9]], float [[CALL9]]) %14 = call contract float @llvm.pow.f32(float %call9, float %call9) - ; CHECK-NEXT: [[TMP15:%.*]] = call contract double @llvm.sqrt.f64(double [[CALL8]]) %15 = call contract double @llvm.sqrt.f64(double %call8) - ; CHECK-NEXT: [[TMP16:%.*]] = call contract float @llvm.sqrt.f32(float [[TMP14]]) %16 = call contract float @llvm.sqrt.f32(float %14) - ; CHECK-NEXT: [[CALL10:%.*]] = call contract double @__hipstdpar_cbrt_f64(double noundef [[TMP15]]) #[[ATTR4]] %call10 = call contract double @cbrt(double noundef %15) #4 - ; CHECK-NEXT: [[CALL11:%.*]] = call contract float @__hipstdpar_cbrt_f32(float noundef [[TMP16]]) #[[ATTR4]] %call11 = call contract float @cbrtf(float noundef %16) #4 - ; CHECK-NEXT: [[CALL12:%.*]] = call contract double @__hipstdpar_hypot_f64(double noundef [[CALL10]], double noundef [[CALL10]]) #[[ATTR4]] %call12 = call contract double @hypot(double noundef %call10, double noundef %call10) #4 - ; CHECK-NEXT: [[CALL13:%.*]] = call contract float @__hipstdpar_hypot_f32(float noundef [[CALL11]], float noundef [[CALL11]]) #[[ATTR4]] %call13 = call contract float @hypotf(float noundef %call11, float noundef %call11) #4 - ; CHECK-NEXT: [[TMP17:%.*]] = call contract float @llvm.sin.f32(float [[CALL13]]) %17 = call contract float @llvm.sin.f32(float %call13) - ; CHECK-NEXT: [[TMP18:%.*]] = call contract float @llvm.cos.f32(float [[TMP17]]) %18 = call contract float @llvm.cos.f32(float %17) - ; CHECK-NEXT: [[TMP19:%.*]] = call contract double @__hipstdpar_tan_f64(double [[CALL12]]) %19 = call contract double @llvm.tan.f64(double %call12) - ; CHECK-NEXT: [[TMP20:%.*]] = call contract double @__hipstdpar_asin_f64(double [[TMP19]]) %20 = call contract double @llvm.asin.f64(double %19) - ; CHECK-NEXT: [[TMP21:%.*]] = call contract double @__hipstdpar_acos_f64(double [[TMP20]]) %21 = call contract double @llvm.acos.f64(double %20) - ; CHECK-NEXT: [[TMP22:%.*]] = call contract double @__hipstdpar_atan_f64(double [[TMP21]]) %22 = call contract double @llvm.atan.f64(double %21) - ; CHECK-NEXT: [[TMP23:%.*]] = call contract double @__hipstdpar_atan2_f64(double [[TMP22]], double [[TMP22]]) %23 = call contract double @llvm.atan2.f64(double %22, double %22) - ; CHECK-NEXT: [[TMP24:%.*]] = call contract double @__hipstdpar_sinh_f64(double [[TMP23]]) %24 = call contract double @llvm.sinh.f64(double %23) - ; CHECK-NEXT: [[TMP25:%.*]] = call contract double @__hipstdpar_cosh_f64(double [[TMP24]]) %25 = call contract double @llvm.cosh.f64(double %24) - ; CHECK-NEXT: [[TMP26:%.*]] = call contract double @__hipstdpar_tanh_f64(double [[TMP25]]) %26 = call contract double @llvm.tanh.f64(double %25) - ; CHECK-NEXT: [[CALL14:%.*]] = call contract double @__hipstdpar_asinh_f64(double noundef [[TMP26]]) #[[ATTR4]] %call14 = call contract double @asinh(double noundef %26) #4 - ; CHECK-NEXT: [[CALL15:%.*]] = call contract float @__hipstdpar_asinh_f32(float noundef [[TMP18]]) #[[ATTR4]] %call15 = call contract float @asinhf(float noundef %18) #4 - ; CHECK-NEXT: [[CALL16:%.*]] = call contract double @__hipstdpar_acosh_f64(double noundef [[CALL14]]) #[[ATTR4]] %call16 = call contract double @acosh(double noundef %call14) #4 - ; CHECK-NEXT: [[CALL17:%.*]] = call contract float @__hipstdpar_acosh_f32(float noundef [[CALL15]]) #[[ATTR4]] %call17 = call contract float @acoshf(float noundef %call15) #4 - ; CHECK-NEXT: [[CALL18:%.*]] = call contract double @__hipstdpar_atanh_f64(double noundef [[CALL16]]) #[[ATTR4]] %call18 = call contract double @atanh(double noundef %call16) #4 - ; CHECK-NEXT: [[CALL19:%.*]] = call contract float @__hipstdpar_atanh_f32(float noundef [[CALL17]]) #[[ATTR4]] %call19 = call contract float @atanhf(float noundef %call17) #4 - ; CHECK-NEXT: [[CALL20:%.*]] = call contract double @__hipstdpar_erf_f64(double noundef [[CALL18]]) #[[ATTR4]] %call20 = call contract double @erf(double noundef %call18) #4 - ; CHECK-NEXT: [[CALL21:%.*]] = call contract float @__hipstdpar_erf_f32(float noundef [[CALL19]]) #[[ATTR4]] %call21 = call contract float @erff(float noundef %call19) #4 - ; CHECK-NEXT: [[CALL22:%.*]] = call contract double @__hipstdpar_erfc_f64(double noundef [[CALL20]]) #[[ATTR4]] %call22 = call contract double @erfc(double noundef %call20) #4 - ; CHECK-NEXT: [[CALL23:%.*]] = call contract float @__hipstdpar_erfc_f32(float noundef [[CALL21]]) #[[ATTR4]] %call23 = call contract float @erfcf(float noundef %call21) #4 - ; CHECK-NEXT: [[CALL24:%.*]] = call contract double @__hipstdpar_tgamma_f64(double noundef [[CALL22]]) #[[ATTR4]] %call24 = call contract double @tgamma(double noundef %call22) #4 - ; CHECK-NEXT: [[CALL25:%.*]] = call contract float @__hipstdpar_tgamma_f32(float noundef [[CALL23]]) #[[ATTR4]] %call25 = call contract float @tgammaf(float noundef %call23) #4 - ; CHECK-NEXT: [[CALL26:%.*]] = call contract double @__hipstdpar_lgamma_f64(double noundef [[CALL24]]) #[[ATTR3]] %call26 = call contract double @lgamma(double noundef %call24) #5 - ; CHECK-NEXT: [[CALL27:%.*]] = call contract float @__hipstdpar_lgamma_f32(float noundef [[CALL25]]) #[[ATTR3]] %call27 = call contract float @lgammaf(float noundef %call25) #5 ret void } From c7f7886f92103b5f41e01a7b30a2f2574e9b259c Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Tue, 20 May 2025 17:36:00 +0300 Subject: [PATCH 06/13] Remove spurious use of `move`. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index 30a0edad6c69a..659dff7347585 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -428,7 +428,7 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, } } - ToReplace.emplace_back(&F, std::move(N)); + ToReplace.emplace_back(&F, N); llvm::replace(ToReplace.back().second, '.', '_'); ToReplace.back().second.replace(0, sizeof("llvm"), "__hipstdpar_"); } From 807f048a926d3169af745f070f0d2e8379f6460f Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Tue, 20 May 2025 19:37:41 +0300 Subject: [PATCH 07/13] Refactor prefix replacement. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index 659dff7347585..32b5b4a50954e 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -430,7 +430,8 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, ToReplace.emplace_back(&F, N); llvm::replace(ToReplace.back().second, '.', '_'); - ToReplace.back().second.replace(0, sizeof("llvm"), "__hipstdpar_"); + StringRef Prefix = "llvm"; + ToReplace.back().second.replace(0, Prefix.size(), "__hipstdpar"); } for (auto &&F : ToReplace) F.first->replaceAllUsesWith( From 375c2f4c7ffd9c678e13f80385f4295b9aafe210 Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Fri, 23 May 2025 01:19:17 +0300 Subject: [PATCH 08/13] Use structured bindings. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index 32b5b4a50954e..b131f34b06d6d 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -433,10 +433,9 @@ PreservedAnalyses HipStdParMathFixupPass::run(Module &M, StringRef Prefix = "llvm"; ToReplace.back().second.replace(0, Prefix.size(), "__hipstdpar"); } - for (auto &&F : ToReplace) - F.first->replaceAllUsesWith( - M.getOrInsertFunction(F.second, F.first->getFunctionType()) - .getCallee()); + for (auto &&[F, NewF] : ToReplace) + F->replaceAllUsesWith( + M.getOrInsertFunction(NewF, F->getFunctionType()).getCallee()); return PreservedAnalyses::none(); } From c51a091bfab2c856bf41e17089c20a1ff22a094b Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Fri, 23 May 2025 02:20:36 +0300 Subject: [PATCH 09/13] Refactor test. --- llvm/test/Transforms/HipStdPar/math-fixup.ll | 619 +++++++++++++------ 1 file changed, 437 insertions(+), 182 deletions(-) diff --git a/llvm/test/Transforms/HipStdPar/math-fixup.ll b/llvm/test/Transforms/HipStdPar/math-fixup.ll index 819f33a2e96f8..bba9ca5611d00 100644 --- a/llvm/test/Transforms/HipStdPar/math-fixup.ll +++ b/llvm/test/Transforms/HipStdPar/math-fixup.ll @@ -1,243 +1,498 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S -passes=hipstdpar-math-fixup %s | FileCheck %s -define void @foo(double noundef %dbl, float noundef %flt, i32 noundef %quo) #0 { -; CHECK-LABEL: define void @foo( -; CHECK-SAME: double noundef [[DBL:%.*]], float noundef [[FLT:%.*]], i32 noundef [[QUO:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[QUO_ADDR:%.*]] = alloca i32, align 4 -; CHECK-NEXT: store i32 [[QUO]], ptr [[QUO_ADDR]], align 4 -; CHECK-NEXT: [[TMP0:%.*]] = tail call contract double @llvm.fabs.f64(double [[DBL]]) -; CHECK-NEXT: [[TMP1:%.*]] = tail call contract float @llvm.fabs.f32(float [[FLT]]) -; CHECK-NEXT: [[CALL:%.*]] = tail call contract double @__hipstdpar_remainder_f64(double noundef [[TMP0]], double noundef [[TMP0]]) #[[ATTR4:[0-9]+]] -; CHECK-NEXT: [[CALL1:%.*]] = tail call contract float @__hipstdpar_remainder_f32(float noundef [[TMP1]], float noundef [[TMP1]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL2:%.*]] = call contract double @__hipstdpar_remquo_f64(double noundef [[CALL]], double noundef [[CALL]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3:[0-9]+]] -; CHECK-NEXT: [[CALL3:%.*]] = call contract float @__hipstdpar_remquo_f32(float noundef [[CALL1]], float noundef [[CALL1]], ptr noundef nonnull [[QUO_ADDR]]) #[[ATTR3]] -; CHECK-NEXT: [[TMP2:%.*]] = call contract double @llvm.fma.f64(double [[CALL2]], double [[CALL2]], double [[CALL2]]) -; CHECK-NEXT: [[TMP3:%.*]] = call contract float @llvm.fma.f32(float [[CALL3]], float [[CALL3]], float [[CALL3]]) -; CHECK-NEXT: [[CALL4:%.*]] = call contract double @__hipstdpar_fdim_f64(double noundef [[TMP2]], double noundef [[TMP2]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL5:%.*]] = call contract float @__hipstdpar_fdim_f32(float noundef [[TMP3]], float noundef [[TMP3]]) #[[ATTR4]] -; CHECK-NEXT: [[TMP4:%.*]] = call contract double @__hipstdpar_exp_f64(double [[CALL4]]) -; CHECK-NEXT: [[TMP5:%.*]] = call contract float @llvm.exp.f32(float [[CALL5]]) -; CHECK-NEXT: [[TMP6:%.*]] = call contract double @__hipstdpar_exp2_f64(double [[TMP4]]) -; CHECK-NEXT: [[TMP7:%.*]] = call contract float @llvm.exp2.f32(float [[TMP5]]) -; CHECK-NEXT: [[CALL6:%.*]] = call contract double @__hipstdpar_expm1_f64(double noundef [[TMP6]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL7:%.*]] = call contract float @__hipstdpar_expm1_f32(float noundef [[TMP7]]) #[[ATTR4]] -; CHECK-NEXT: [[TMP8:%.*]] = call contract double @__hipstdpar_log_f64(double [[CALL6]]) -; CHECK-NEXT: [[TMP9:%.*]] = call contract float @llvm.log.f32(float [[CALL7]]) -; CHECK-NEXT: [[TMP10:%.*]] = call contract double @__hipstdpar_log10_f64(double [[TMP8]]) -; CHECK-NEXT: [[TMP11:%.*]] = call contract float @llvm.log10.f32(float [[TMP9]]) -; CHECK-NEXT: [[TMP12:%.*]] = call contract double @__hipstdpar_log2_f64(double [[TMP10]]) -; CHECK-NEXT: [[TMP13:%.*]] = call contract float @llvm.log2.f32(float [[TMP11]]) -; CHECK-NEXT: [[CALL8:%.*]] = call contract double @__hipstdpar_log1p_f64(double noundef [[TMP12]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL9:%.*]] = call contract float @__hipstdpar_log1p_f32(float noundef [[TMP13]]) #[[ATTR4]] -; CHECK-NEXT: [[TMP14:%.*]] = call contract float @llvm.pow.f32(float [[CALL9]], float [[CALL9]]) -; CHECK-NEXT: [[TMP15:%.*]] = call contract double @llvm.sqrt.f64(double [[CALL8]]) -; CHECK-NEXT: [[TMP16:%.*]] = call contract float @llvm.sqrt.f32(float [[TMP14]]) -; CHECK-NEXT: [[CALL10:%.*]] = call contract double @__hipstdpar_cbrt_f64(double noundef [[TMP15]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL11:%.*]] = call contract float @__hipstdpar_cbrt_f32(float noundef [[TMP16]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL12:%.*]] = call contract double @__hipstdpar_hypot_f64(double noundef [[CALL10]], double noundef [[CALL10]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL13:%.*]] = call contract float @__hipstdpar_hypot_f32(float noundef [[CALL11]], float noundef [[CALL11]]) #[[ATTR4]] -; CHECK-NEXT: [[TMP17:%.*]] = call contract float @llvm.sin.f32(float [[CALL13]]) -; CHECK-NEXT: [[TMP18:%.*]] = call contract float @llvm.cos.f32(float [[TMP17]]) -; CHECK-NEXT: [[TMP19:%.*]] = call contract double @__hipstdpar_tan_f64(double [[CALL12]]) -; CHECK-NEXT: [[TMP20:%.*]] = call contract double @__hipstdpar_asin_f64(double [[TMP19]]) -; CHECK-NEXT: [[TMP21:%.*]] = call contract double @__hipstdpar_acos_f64(double [[TMP20]]) -; CHECK-NEXT: [[TMP22:%.*]] = call contract double @__hipstdpar_atan_f64(double [[TMP21]]) -; CHECK-NEXT: [[TMP23:%.*]] = call contract double @__hipstdpar_atan2_f64(double [[TMP22]], double [[TMP22]]) -; CHECK-NEXT: [[TMP24:%.*]] = call contract double @__hipstdpar_sinh_f64(double [[TMP23]]) -; CHECK-NEXT: [[TMP25:%.*]] = call contract double @__hipstdpar_cosh_f64(double [[TMP24]]) -; CHECK-NEXT: [[TMP26:%.*]] = call contract double @__hipstdpar_tanh_f64(double [[TMP25]]) -; CHECK-NEXT: [[CALL14:%.*]] = call contract double @__hipstdpar_asinh_f64(double noundef [[TMP26]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL15:%.*]] = call contract float @__hipstdpar_asinh_f32(float noundef [[TMP18]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL16:%.*]] = call contract double @__hipstdpar_acosh_f64(double noundef [[CALL14]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL17:%.*]] = call contract float @__hipstdpar_acosh_f32(float noundef [[CALL15]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL18:%.*]] = call contract double @__hipstdpar_atanh_f64(double noundef [[CALL16]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL19:%.*]] = call contract float @__hipstdpar_atanh_f32(float noundef [[CALL17]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL20:%.*]] = call contract double @__hipstdpar_erf_f64(double noundef [[CALL18]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL21:%.*]] = call contract float @__hipstdpar_erf_f32(float noundef [[CALL19]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL22:%.*]] = call contract double @__hipstdpar_erfc_f64(double noundef [[CALL20]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL23:%.*]] = call contract float @__hipstdpar_erfc_f32(float noundef [[CALL21]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL24:%.*]] = call contract double @__hipstdpar_tgamma_f64(double noundef [[CALL22]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL25:%.*]] = call contract float @__hipstdpar_tgamma_f32(float noundef [[CALL23]]) #[[ATTR4]] -; CHECK-NEXT: [[CALL26:%.*]] = call contract double @__hipstdpar_lgamma_f64(double noundef [[CALL24]]) #[[ATTR3]] -; CHECK-NEXT: [[CALL27:%.*]] = call contract float @__hipstdpar_lgamma_f32(float noundef [[CALL25]]) #[[ATTR3]] -; CHECK-NEXT: ret void -; -entry: - %quo.addr = alloca i32, align 4 - store i32 %quo, ptr %quo.addr, align 4 - %0 = tail call contract double @llvm.fabs.f64(double %dbl) - %1 = tail call contract float @llvm.fabs.f32(float %flt) - %call = tail call contract double @remainder(double noundef %0, double noundef %0) #4 - %call1 = tail call contract float @remainderf(float noundef %1, float noundef %1) #4 - %call2 = call contract double @remquo(double noundef %call, double noundef %call, ptr noundef nonnull %quo.addr) #5 - %call3 = call contract float @remquof(float noundef %call1, float noundef %call1, ptr noundef nonnull %quo.addr) #5 - %2 = call contract double @llvm.fma.f64(double %call2, double %call2, double %call2) - %3 = call contract float @llvm.fma.f32(float %call3, float %call3, float %call3) - %call4 = call contract double @fdim(double noundef %2, double noundef %2) #4 - %call5 = call contract float @fdimf(float noundef %3, float noundef %3) #4 - %4 = call contract double @llvm.exp.f64(double %call4) - %5 = call contract float @llvm.exp.f32(float %call5) - %6 = call contract double @llvm.exp2.f64(double %4) - %7 = call contract float @llvm.exp2.f32(float %5) - %call6 = call contract double @expm1(double noundef %6) #4 - %call7 = call contract float @expm1f(float noundef %7) #4 - %8 = call contract double @llvm.log.f64(double %call6) - %9 = call contract float @llvm.log.f32(float %call7) - %10 = call contract double @llvm.log10.f64(double %8) - %11 = call contract float @llvm.log10.f32(float %9) - %12 = call contract double @llvm.log2.f64(double %10) - %13 = call contract float @llvm.log2.f32(float %11) - %call8 = call contract double @log1p(double noundef %12) #4 - %call9 = call contract float @log1pf(float noundef %13) #4 - %14 = call contract float @llvm.pow.f32(float %call9, float %call9) - %15 = call contract double @llvm.sqrt.f64(double %call8) - %16 = call contract float @llvm.sqrt.f32(float %14) - %call10 = call contract double @cbrt(double noundef %15) #4 - %call11 = call contract float @cbrtf(float noundef %16) #4 - %call12 = call contract double @hypot(double noundef %call10, double noundef %call10) #4 - %call13 = call contract float @hypotf(float noundef %call11, float noundef %call11) #4 - %17 = call contract float @llvm.sin.f32(float %call13) - %18 = call contract float @llvm.cos.f32(float %17) - %19 = call contract double @llvm.tan.f64(double %call12) - %20 = call contract double @llvm.asin.f64(double %19) - %21 = call contract double @llvm.acos.f64(double %20) - %22 = call contract double @llvm.atan.f64(double %21) - %23 = call contract double @llvm.atan2.f64(double %22, double %22) - %24 = call contract double @llvm.sinh.f64(double %23) - %25 = call contract double @llvm.cosh.f64(double %24) - %26 = call contract double @llvm.tanh.f64(double %25) - %call14 = call contract double @asinh(double noundef %26) #4 - %call15 = call contract float @asinhf(float noundef %18) #4 - %call16 = call contract double @acosh(double noundef %call14) #4 - %call17 = call contract float @acoshf(float noundef %call15) #4 - %call18 = call contract double @atanh(double noundef %call16) #4 - %call19 = call contract float @atanhf(float noundef %call17) #4 - %call20 = call contract double @erf(double noundef %call18) #4 - %call21 = call contract float @erff(float noundef %call19) #4 - %call22 = call contract double @erfc(double noundef %call20) #4 - %call23 = call contract float @erfcf(float noundef %call21) #4 - %call24 = call contract double @tgamma(double noundef %call22) #4 - %call25 = call contract float @tgammaf(float noundef %call23) #4 - %call26 = call contract double @lgamma(double noundef %call24) #5 - %call27 = call contract float @lgammaf(float noundef %call25) #5 +define void @test_acos(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_acos( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_acos_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_acos_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.acos.f64(double %dbl) + %1 = call float @llvm.acos.f32(float %flt) ret void } -declare double @llvm.fabs.f64(double) #1 +define void @test_acosh(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_acosh( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_acosh_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_acosh_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @acosh(double %dbl) + %1 = call float @acoshf(float %flt) + ret void +} -declare float @llvm.fabs.f32(float) #1 +define void @test_asin(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_asin( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_asin_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_asin_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.asin.f64(double %dbl) + %1 = call float @llvm.asin.f32(float %flt) + ret void +} -declare hidden double @remainder(double noundef, double noundef) local_unnamed_addr #2 +define void @test_asinh(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_asinh( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_asinh_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_asinh_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @asinh(double %dbl) + %1 = call float @asinhf(float %flt) + ret void +} -declare hidden float @remainderf(float noundef, float noundef) local_unnamed_addr #2 +define void @test_atan(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_atan( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_atan_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_atan_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.atan.f64(double %dbl) + %1 = call float @llvm.atan.f32(float %flt) + ret void +} -declare hidden double @remquo(double noundef, double noundef, ptr noundef) local_unnamed_addr #3 +define void @test_atanh(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_atanh( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_atanh_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_atanh_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @atanh(double %dbl) + %1 = call float @atanhf(float %flt) + ret void +} -declare hidden float @remquof(float noundef, float noundef, ptr noundef) local_unnamed_addr #3 +define void @test_atan2(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_atan2( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_atan2_f64(double [[DBL]], double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_atan2_f32(float [[FLT]], float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.atan2.f64(double %dbl, double %dbl) + %1 = call float @llvm.atan2.f32(float %flt, float %flt) + ret void +} -declare double @llvm.fma.f64(double, double, double) #1 +define void @test_cbrt(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_cbrt( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_cbrt_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_cbrt_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @cbrt(double %dbl) + %1 = call float @cbrtf(float %flt) + ret void +} -declare float @llvm.fma.f32(float, float, float) #1 +define void @test_cos(double %dbl) { +; CHECK-LABEL: define void @test_cos( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_cos_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.cos.f64(double %dbl) + ret void +} -declare hidden double @fdim(double noundef, double noundef) local_unnamed_addr #2 +define void @test_cosh(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_cosh( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_cosh_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_cosh_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.cosh.f64(double %dbl) + %1 = call float @llvm.cosh.f32(float %flt) + ret void +} -declare hidden float @fdimf(float noundef, float noundef) local_unnamed_addr #2 +define void @test_erf(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_erf( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_erf_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_erf_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @erf(double %dbl) + %1 = call float @erff(float %flt) + ret void +} + +define void @test_erfc(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_erfc( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_erfc_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_erfc_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @erfc(double %dbl) + %1 = call float @erfcf(float %flt) + ret void +} + +define void @test_exp(double %dbl) { +; CHECK-LABEL: define void @test_exp( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_exp_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.exp.f64(double %dbl) + ret void +} + +define void @test_exp2(double %dbl) { +; CHECK-LABEL: define void @test_exp2( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_exp2_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.exp2.f64(double %dbl) + ret void +} + +define void @test_expm1(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_expm1( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_expm1_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_expm1_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @expm1(double %dbl) + %1 = call float @expm1f(float %flt) + ret void +} + +define void @test_fdim(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_fdim( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_fdim_f64(double [[DBL]], double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_fdim_f32(float [[FLT]], float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @fdim(double %dbl, double %dbl) + %1 = call float @fdimf(float %flt, float %flt) + ret void +} + +define void @test_hypot(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_hypot( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_hypot_f64(double [[DBL]], double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_hypot_f32(float [[FLT]], float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @hypot(double %dbl, double %dbl) + %1 = call float @hypotf(float %flt, float %flt) + ret void +} + +define void @test_lgamma(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_lgamma( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_lgamma_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_lgamma_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @lgamma(double %dbl) + %1 = call float @lgammaf(float %flt) + ret void +} + +define void @test_log(double %dbl) { +; CHECK-LABEL: define void @test_log( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_log_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.log.f64(double %dbl) + ret void +} + +define void @test_log10(double %dbl) { +; CHECK-LABEL: define void @test_log10( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_log10_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.log10.f64(double %dbl) + ret void +} + +define void @test_log2(double %dbl) { +; CHECK-LABEL: define void @test_log2( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_log2_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.log2.f64(double %dbl) + ret void +} + +define void @test_log1p(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_log1p( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_log1p_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_log1p_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @log1p(double %dbl) + %1 = call float @log1pf(float %flt) + ret void +} + +define void @test_pow(double %dbl) { +; CHECK-LABEL: define void @test_pow( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_pow_f64(double [[DBL]], double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.pow.f64(double %dbl, double %dbl) + ret void +} + +define void @test_remainder(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_remainder( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_remainder_f64(double [[DBL]], double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_remainder_f32(float [[FLT]], float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @remainder(double %dbl, double %dbl) + %1 = call float @remainderf(float %flt, float %flt) + ret void +} + +define void @test_remquo(double %dbl, float %flt, ptr %p) { +; CHECK-LABEL: define void @test_remquo( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_remquo_f64(double [[DBL]], double [[DBL]], ptr [[P]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_remquo_f32(float [[FLT]], float [[FLT]], ptr [[P]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @remquo(double %dbl, double %dbl, ptr %p) + %1 = call float @remquof(float %flt, float %flt, ptr %p) + ret void +} + +define void @test_sin(double %dbl) { +; CHECK-LABEL: define void @test_sin( +; CHECK-SAME: double [[DBL:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_sin_f64(double [[DBL]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.sin.f64(double %dbl) + ret void +} + +define void @test_sinh(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_sinh( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_sinh_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_sinh_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.sinh.f64(double %dbl) + %1 = call float @llvm.sinh.f32(float %flt) + ret void +} + +define void @test_tan(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_tan( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_tan_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_tan_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.tan.f64(double %dbl) + %1 = call float @llvm.tan.f32(float %flt) + ret void +} + +define void @test_tanh(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_tanh( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_tanh_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_tanh_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @llvm.tanh.f64(double %dbl) + %1 = call float @llvm.tanh.f32(float %flt) + ret void +} + +define void @test_tgamma(double %dbl, float %flt) { +; CHECK-LABEL: define void @test_tgamma( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_tgamma_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_tgamma_f32(float [[FLT]]) +; CHECK-NEXT: ret void +; +entry: + %0 = call double @tgamma(double %dbl) + %1 = call float @tgammaf(float %flt) + ret void +} -declare double @llvm.exp.f64(double) #1 +declare hidden double @remainder(double, double) local_unnamed_addr -declare float @llvm.exp.f32(float) #1 +declare hidden float @remainderf(float, float) local_unnamed_addr -declare double @llvm.exp2.f64(double) #1 +declare hidden double @remquo(double, double, ptr) local_unnamed_addr -declare float @llvm.exp2.f32(float) #1 +declare hidden float @remquof(float, float, ptr) local_unnamed_addr -declare hidden double @expm1(double noundef) local_unnamed_addr #2 +declare hidden double @fdim(double, double) local_unnamed_addr -declare hidden float @expm1f(float noundef) local_unnamed_addr #2 +declare hidden float @fdimf(float, float) local_unnamed_addr -declare double @llvm.log.f64(double) #1 +declare double @llvm.exp.f64(double) -declare float @llvm.log.f32(float) #1 +declare float @llvm.exp.f32(float) -declare double @llvm.log10.f64(double) #1 +declare double @llvm.exp2.f64(double) -declare float @llvm.log10.f32(float) #1 +declare float @llvm.exp2.f32(float) -declare double @llvm.log2.f64(double) #1 +declare hidden double @expm1(double) local_unnamed_addr -declare float @llvm.log2.f32(float) #1 +declare hidden float @expm1f(float) local_unnamed_addr -declare hidden double @log1p(double noundef) local_unnamed_addr #2 +declare double @llvm.log.f64(double) -declare hidden float @log1pf(float noundef) local_unnamed_addr #2 +declare double @llvm.log10.f64(double) -declare float @llvm.pow.f32(float, float) #1 +declare double @llvm.log2.f64(double) -declare double @llvm.sqrt.f64(double) #1 +declare hidden double @log1p(double) local_unnamed_addr -declare float @llvm.sqrt.f32(float) #1 +declare hidden float @log1pf(float) local_unnamed_addr -declare hidden double @cbrt(double noundef) local_unnamed_addr #2 +declare double @llvm.pow.f64(double, double) -declare hidden float @cbrtf(float noundef) local_unnamed_addr #2 +declare hidden double @cbrt(double) local_unnamed_addr -declare hidden double @hypot(double noundef, double noundef) local_unnamed_addr #2 +declare hidden float @cbrtf(float) local_unnamed_addr -declare hidden float @hypotf(float noundef, float noundef) local_unnamed_addr #2 +declare hidden double @hypot(double, double) local_unnamed_addr -declare float @llvm.sin.f32(float) #1 +declare hidden float @hypotf(float, float) local_unnamed_addr -declare float @llvm.cos.f32(float) #1 +declare double @llvm.sin.f64(double) -declare double @llvm.tan.f64(double) #1 +declare double @llvm.cos.f64(double) -declare double @llvm.asin.f64(double) #1 +declare double @llvm.tan.f64(double) -declare double @llvm.acos.f64(double) #1 +declare double @llvm.asin.f64(double) -declare double @llvm.atan.f64(double) #1 +declare double @llvm.acos.f64(double) -declare double @llvm.atan2.f64(double, double) #1 +declare double @llvm.atan.f64(double) -declare double @llvm.sinh.f64(double) #1 +declare double @llvm.atan2.f64(double, double) -declare double @llvm.cosh.f64(double) #1 +declare double @llvm.sinh.f64(double) -declare double @llvm.tanh.f64(double) #1 +declare double @llvm.cosh.f64(double) -declare hidden double @asinh(double noundef) local_unnamed_addr #2 +declare double @llvm.tanh.f64(double) -declare hidden float @asinhf(float noundef) local_unnamed_addr #2 +declare hidden double @asinh(double) local_unnamed_addr -declare hidden double @acosh(double noundef) local_unnamed_addr #2 +declare hidden float @asinhf(float) local_unnamed_addr -declare hidden float @acoshf(float noundef) local_unnamed_addr #2 +declare hidden double @acosh(double) local_unnamed_addr -declare hidden double @atanh(double noundef) local_unnamed_addr #2 +declare hidden float @acoshf(float) local_unnamed_addr -declare hidden float @atanhf(float noundef) local_unnamed_addr #2 +declare hidden double @atanh(double) local_unnamed_addr -declare hidden double @erf(double noundef) local_unnamed_addr #2 +declare hidden float @atanhf(float) local_unnamed_addr -declare hidden float @erff(float noundef) local_unnamed_addr #2 +declare hidden double @erf(double) local_unnamed_addr -declare hidden double @erfc(double noundef) local_unnamed_addr #2 +declare hidden float @erff(float) local_unnamed_addr -declare hidden float @erfcf(float noundef) local_unnamed_addr #2 +declare hidden double @erfc(double) local_unnamed_addr -declare hidden double @tgamma(double noundef) local_unnamed_addr #2 +declare hidden float @erfcf(float) local_unnamed_addr -declare hidden float @tgammaf(float noundef) local_unnamed_addr #2 +declare hidden double @tgamma(double) local_unnamed_addr -declare hidden double @lgamma(double noundef) local_unnamed_addr #3 +declare hidden float @tgammaf(float) local_unnamed_addr -declare hidden float @lgammaf(float noundef) local_unnamed_addr #3 +declare hidden double @lgamma(double) local_unnamed_addr -attributes #0 = { convergent mustprogress norecurse nounwind } -attributes #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) } -attributes #2 = { convergent mustprogress nofree nounwind willreturn memory(none) } -attributes #3 = { convergent nounwind } -attributes #4 = { convergent nounwind willreturn memory(none) } -attributes #5 = { convergent nounwind } +declare hidden float @lgammaf(float) local_unnamed_addr From 7887edb6513a2e8358ac3fab511431ac4e03478a Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Mon, 2 Jun 2025 17:10:56 +0100 Subject: [PATCH 10/13] Clean up more noise. --- llvm/test/Transforms/HipStdPar/math-fixup.ll | 56 ++++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/llvm/test/Transforms/HipStdPar/math-fixup.ll b/llvm/test/Transforms/HipStdPar/math-fixup.ll index bba9ca5611d00..914ad2d264eba 100644 --- a/llvm/test/Transforms/HipStdPar/math-fixup.ll +++ b/llvm/test/Transforms/HipStdPar/math-fixup.ll @@ -405,17 +405,17 @@ entry: ret void } -declare hidden double @remainder(double, double) local_unnamed_addr +declare hidden double @remainder(double, double) -declare hidden float @remainderf(float, float) local_unnamed_addr +declare hidden float @remainderf(float, float) -declare hidden double @remquo(double, double, ptr) local_unnamed_addr +declare hidden double @remquo(double, double, ptr) -declare hidden float @remquof(float, float, ptr) local_unnamed_addr +declare hidden float @remquof(float, float, ptr) -declare hidden double @fdim(double, double) local_unnamed_addr +declare hidden double @fdim(double, double) -declare hidden float @fdimf(float, float) local_unnamed_addr +declare hidden float @fdimf(float, float) declare double @llvm.exp.f64(double) @@ -425,9 +425,9 @@ declare double @llvm.exp2.f64(double) declare float @llvm.exp2.f32(float) -declare hidden double @expm1(double) local_unnamed_addr +declare hidden double @expm1(double) -declare hidden float @expm1f(float) local_unnamed_addr +declare hidden float @expm1f(float) declare double @llvm.log.f64(double) @@ -435,19 +435,19 @@ declare double @llvm.log10.f64(double) declare double @llvm.log2.f64(double) -declare hidden double @log1p(double) local_unnamed_addr +declare hidden double @log1p(double) -declare hidden float @log1pf(float) local_unnamed_addr +declare hidden float @log1pf(float) declare double @llvm.pow.f64(double, double) -declare hidden double @cbrt(double) local_unnamed_addr +declare hidden double @cbrt(double) -declare hidden float @cbrtf(float) local_unnamed_addr +declare hidden float @cbrtf(float) -declare hidden double @hypot(double, double) local_unnamed_addr +declare hidden double @hypot(double, double) -declare hidden float @hypotf(float, float) local_unnamed_addr +declare hidden float @hypotf(float, float) declare double @llvm.sin.f64(double) @@ -469,30 +469,30 @@ declare double @llvm.cosh.f64(double) declare double @llvm.tanh.f64(double) -declare hidden double @asinh(double) local_unnamed_addr +declare hidden double @asinh(double) -declare hidden float @asinhf(float) local_unnamed_addr +declare hidden float @asinhf(float) -declare hidden double @acosh(double) local_unnamed_addr +declare hidden double @acosh(double) -declare hidden float @acoshf(float) local_unnamed_addr +declare hidden float @acoshf(float) -declare hidden double @atanh(double) local_unnamed_addr +declare hidden double @atanh(double) -declare hidden float @atanhf(float) local_unnamed_addr +declare hidden float @atanhf(float) -declare hidden double @erf(double) local_unnamed_addr +declare hidden double @erf(double) -declare hidden float @erff(float) local_unnamed_addr +declare hidden float @erff(float) -declare hidden double @erfc(double) local_unnamed_addr +declare hidden double @erfc(double) -declare hidden float @erfcf(float) local_unnamed_addr +declare hidden float @erfcf(float) -declare hidden double @tgamma(double) local_unnamed_addr +declare hidden double @tgamma(double) -declare hidden float @tgammaf(float) local_unnamed_addr +declare hidden float @tgammaf(float) -declare hidden double @lgamma(double) local_unnamed_addr +declare hidden double @lgamma(double) -declare hidden float @lgammaf(float) local_unnamed_addr +declare hidden float @lgammaf(float) From 1167cc01bb3b3e5ff01de8048e1a20c80a4ee8b7 Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Tue, 15 Jul 2025 18:05:30 +0100 Subject: [PATCH 11/13] Add missing `modf` test. --- llvm/test/Transforms/HipStdPar/math-fixup.ll | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/llvm/test/Transforms/HipStdPar/math-fixup.ll b/llvm/test/Transforms/HipStdPar/math-fixup.ll index 914ad2d264eba..b240514db2771 100644 --- a/llvm/test/Transforms/HipStdPar/math-fixup.ll +++ b/llvm/test/Transforms/HipStdPar/math-fixup.ll @@ -297,6 +297,32 @@ entry: ret void } +define void @test_modf(double %dbl, float %flt, ptr %pdbl, ptr %pflt) { +; CHECK-LABEL: define void @test_modf( +; CHECK-SAME: double [[DBL:%.*]], float [[FLT:%.*]], ptr [[PDBL:%.*]], ptr [[PFLT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = tail call { double, double } @__hipstdpar_modf_f64(double [[DBL]]) +; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { double, double } [[TMP0]], 0 +; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { double, double } [[TMP0]], 1 +; CHECK-NEXT: store double [[TMP2]], ptr [[PDBL]], align 8 +; CHECK-NEXT: [[TMP3:%.*]] = tail call { float, float } @__hipstdpar_modf_f32(float [[FLT]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { float, float } [[TMP3]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue { float, float } [[TMP3]], 1 +; CHECK-NEXT: store float [[TMP5]], ptr [[PFLT]], align 4 +; CHECK-NEXT: ret void +; +entry: + %0 = tail call { double, double } @llvm.modf.f64(double %dbl) + %1 = extractvalue { double, double } %0, 0 + %2 = extractvalue { double, double } %0, 1 + store double %2, ptr %pdbl, align 8 + %3 = tail call { float, float } @llvm.modf.f32(float %flt) + %4 = extractvalue { float, float } %3, 0 + %5 = extractvalue { float, float } %3, 1 + store float %5, ptr %pflt, align 4 + ret void +} + define void @test_pow(double %dbl) { ; CHECK-LABEL: define void @test_pow( ; CHECK-SAME: double [[DBL:%.*]]) { @@ -439,6 +465,10 @@ declare hidden double @log1p(double) declare hidden float @log1pf(float) +declare { float, float } @llvm.modf.f32(float) + +declare { double, double } @llvm.modf.f64(double) + declare double @llvm.pow.f64(double, double) declare hidden double @cbrt(double) From e40a70ad117b184be0e110978a953e2780ea5a6b Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Tue, 15 Jul 2025 18:52:53 +0100 Subject: [PATCH 12/13] Add test for globals used as args to replaced fn. --- llvm/test/Transforms/HipStdPar/math-fixup.ll | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/llvm/test/Transforms/HipStdPar/math-fixup.ll b/llvm/test/Transforms/HipStdPar/math-fixup.ll index b240514db2771..2c4622cb1f603 100644 --- a/llvm/test/Transforms/HipStdPar/math-fixup.ll +++ b/llvm/test/Transforms/HipStdPar/math-fixup.ll @@ -431,6 +431,26 @@ entry: ret void } +@globdbl = global double 4.200000e+01 +@globflt = global float 4.200000e+01 + +define void @global_args() { +; CHECK-LABEL: define void @global_args() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[DBL:%.*]] = load double, ptr @globdbl, align 8 +; CHECK-NEXT: [[FLT:%.*]] = load float, ptr @globflt, align 4 +; CHECK-NEXT: [[TMP0:%.*]] = call double @__hipstdpar_remquo_f64(double [[DBL]], double [[DBL]], ptr @globdbl) +; CHECK-NEXT: [[TMP1:%.*]] = call float @__hipstdpar_remquo_f32(float [[FLT]], float [[FLT]], ptr @globflt) +; CHECK-NEXT: ret void +; +entry: + %dbl = load double, ptr @globdbl + %flt = load float, ptr @globflt + %1 = call double @remquo(double %dbl, double %dbl, ptr @globdbl) + %2 = call float @remquof(float %flt, float %flt, ptr @globflt) + ret void +} + declare hidden double @remainder(double, double) declare hidden float @remainderf(float, float) From 2767e5cd07169c93384bed1cf0ad1a5855e12b26 Mon Sep 17 00:00:00 2001 From: Alex Voicu Date: Wed, 23 Jul 2025 22:17:26 +0100 Subject: [PATCH 13/13] Update HipStdPar.cpp Fix ordering of includes. --- llvm/lib/Transforms/HipStdPar/HipStdPar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp index 4bbccde6f09e9..d895cd7d78bf6 100644 --- a/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp +++ b/llvm/lib/Transforms/HipStdPar/HipStdPar.cpp @@ -58,8 +58,8 @@ #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Intrinsics.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/Transforms/Utils/ModuleUtils.h"