diff --git a/.github/workflows/check-all.yml b/.github/workflows/check-all.yml index 7dae7547..64f84c3b 100644 --- a/.github/workflows/check-all.yml +++ b/.github/workflows/check-all.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - llvm: ["20"] + llvm: ["20", "21"] build: ["Release"] #, "Debug"] #, "RelWithDebInfo"] os: [ubuntu-22.04] diff --git a/Readme.md b/Readme.md index 1dccb84e..0032f1d3 100644 --- a/Readme.md +++ b/Readme.md @@ -118,16 +118,16 @@ or if using `lld` directly: Suppose your original code looks like this: ``` c++ -void bar(float a, float b) { +float bar(float a, float b) { return a + b; } -void foo(float *a, float b) { +float foo(float *a, float b) { a[0] = sqrt(b); return bar(a[1], b); } ... - foo(a, b) + foo(a, b); ... ``` diff --git a/pass/Raptor.cpp b/pass/Raptor.cpp index d9922510..532b215f 100644 --- a/pass/Raptor.cpp +++ b/pass/Raptor.cpp @@ -102,6 +102,30 @@ llvm::cl::opt RaptorTruncateAccessCount( "raptor-truncate-access-count", cl::init(false), cl::Hidden, cl::desc("Count all floating-point loads and stores.")); +void addNoCapture(CallInst *CI, unsigned ArgNo) { +#if LLVM_VERSION_MAJOR >= 21 + CI->addParamAttr(ArgNo, Attribute::get(CI->getContext(), "captures", "none")); +#else + CI->addParamAttr(ArgNo, Attribute::NoCapture); +#endif +} + +void addNoCapture(llvm::Function *F, llvm::Argument &Arg) { +#if LLVM_VERSION_MAJOR >= 21 + Arg.addAttr(Attribute::get(F->getContext(), "captures", "none")); +#else + Arg.addAttr(Attribute::NoCapture); +#endif +} + +void addNoCapture(llvm::Function *F, unsigned ArgNo) { +#if LLVM_VERSION_MAJOR >= 21 + F->addParamAttr(ArgNo, Attribute::get(F->getContext(), "captures", "none")); +#else + F->addParamAttr(ArgNo, Attribute::NoCapture); +#endif +} + #define addAttribute addAttributeAtIndex #define getAttribute getAttributeAtIndex bool attributeKnownFunctions(llvm::Function &F) { @@ -109,7 +133,7 @@ bool attributeKnownFunctions(llvm::Function &F) { if (F.getName() == "fprintf") { for (auto &arg : F.args()) { if (arg.getType()->isPointerTy()) { - arg.addAttr(Attribute::NoCapture); + addNoCapture(&F, arg); changed = true; } } @@ -132,7 +156,7 @@ bool attributeKnownFunctions(llvm::Function &F) { for (auto &arg : F.args()) { if (arg.getType()->isPointerTy()) { arg.addAttr(Attribute::ReadNone); - arg.addAttr(Attribute::NoCapture); + addNoCapture(&F, arg); } } } @@ -152,7 +176,7 @@ bool attributeKnownFunctions(llvm::Function &F) { F.addFnAttr(Attribute::NoSync); for (int i = 0; i < 2; i++) if (F.getFunctionType()->getParamType(i)->isPointerTy()) { - F.addParamAttr(i, Attribute::NoCapture); + addNoCapture(&F, i); F.addParamAttr(i, Attribute::WriteOnly); } } @@ -176,7 +200,7 @@ bool attributeKnownFunctions(llvm::Function &F) { F.addFnAttr(Attribute::NoSync); F.addParamAttr(0, Attribute::WriteOnly); if (F.getFunctionType()->getParamType(2)->isPointerTy()) { - F.addParamAttr(2, Attribute::NoCapture); + addNoCapture(&F, 2); F.addParamAttr(2, Attribute::WriteOnly); } F.addParamAttr(6, Attribute::WriteOnly); @@ -195,7 +219,7 @@ bool attributeKnownFunctions(llvm::Function &F) { F.addFnAttr(Attribute::NoSync); F.addParamAttr(0, Attribute::ReadOnly); if (F.getFunctionType()->getParamType(2)->isPointerTy()) { - F.addParamAttr(2, Attribute::NoCapture); + addNoCapture(&F, 2); F.addParamAttr(2, Attribute::ReadOnly); } F.addParamAttr(6, Attribute::WriteOnly); @@ -215,12 +239,12 @@ bool attributeKnownFunctions(llvm::Function &F) { F.addFnAttr(Attribute::NoSync); if (F.getFunctionType()->getParamType(0)->isPointerTy()) { - F.addParamAttr(0, Attribute::NoCapture); + addNoCapture(&F, 0); F.addParamAttr(0, Attribute::ReadOnly); } if (F.getFunctionType()->getParamType(1)->isPointerTy()) { F.addParamAttr(1, Attribute::WriteOnly); - F.addParamAttr(1, Attribute::NoCapture); + addNoCapture(&F, 1); } } if (F.getName() == "MPI_Wait" || F.getName() == "PMPI_Wait") { @@ -230,9 +254,9 @@ bool attributeKnownFunctions(llvm::Function &F) { F.addFnAttr(Attribute::WillReturn); F.addFnAttr(Attribute::NoFree); F.addFnAttr(Attribute::NoSync); - F.addParamAttr(0, Attribute::NoCapture); + addNoCapture(&F, 0); + addNoCapture(&F, 1); F.addParamAttr(1, Attribute::WriteOnly); - F.addParamAttr(1, Attribute::NoCapture); } if (F.getName() == "MPI_Waitall" || F.getName() == "PMPI_Waitall") { changed = true; @@ -241,9 +265,9 @@ bool attributeKnownFunctions(llvm::Function &F) { F.addFnAttr(Attribute::WillReturn); F.addFnAttr(Attribute::NoFree); F.addFnAttr(Attribute::NoSync); - F.addParamAttr(1, Attribute::NoCapture); + addNoCapture(&F, 1); + addNoCapture(&F, 2); F.addParamAttr(2, Attribute::WriteOnly); - F.addParamAttr(2, Attribute::NoCapture); } // Map of MPI function name to the arg index of its type argument std::map MPI_TYPE_ARGS = { @@ -825,9 +849,9 @@ class RaptorBase { CI->addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly); #endif CI->addParamAttr(1, Attribute::ReadOnly); - CI->addParamAttr(1, Attribute::NoCapture); CI->addParamAttr(3, Attribute::ReadOnly); - CI->addParamAttr(3, Attribute::NoCapture); + addNoCapture(CI, 1); + addNoCapture(CI, 3); } if (Fn->getName() == "frexp" || Fn->getName() == "frexpf" || Fn->getName() == "frexpl") { @@ -888,7 +912,7 @@ class RaptorBase { for (size_t i : {0, 1}) { if (i < num_args && CI->getArgOperand(i)->getType()->isPointerTy()) { - CI->addParamAttr(i, Attribute::NoCapture); + addNoCapture(CI, i); } } } @@ -913,7 +937,7 @@ class RaptorBase { for (size_t i : {0, 2}) { if (i < num_args && CI->getArgOperand(i)->getType()->isPointerTy()) { - CI->addParamAttr(i, Attribute::NoCapture); + addNoCapture(CI, i); } } } @@ -939,7 +963,7 @@ class RaptorBase { for (size_t i : {0, 1, 2, 3}) { if (i < num_args && CI->getArgOperand(i)->getType()->isPointerTy()) { - CI->addParamAttr(i, Attribute::NoCapture); + addNoCapture(CI, i); } } } @@ -965,7 +989,7 @@ class RaptorBase { for (size_t i : {0}) { if (i < num_args && CI->getArgOperand(i)->getType()->isPointerTy()) { - CI->addParamAttr(i, Attribute::NoCapture); + addNoCapture(CI, i); } } } @@ -987,7 +1011,7 @@ class RaptorBase { for (size_t i = 0; i < num_args; ++i) { if (CI->getArgOperand(i)->getType()->isPointerTy()) { CI->addParamAttr(i, Attribute::ReadOnly); - CI->addParamAttr(i, Attribute::NoCapture); + addNoCapture(CI, i); } } } @@ -1485,7 +1509,6 @@ void augmentPassBuilder(llvm::PassBuilder &PB) { FPM.addPass(JumpThreadingPass()); - // Break up allocas FPM.addPass(SROAPass(SROAOptions::ModifyCFG)); diff --git a/test/Integration/Truncate/Fortran/simple-no-bindc.f90 b/test/Integration/Truncate/Fortran/simple-no-bindc.f90 index 2ac8b5f5..79f48165 100644 --- a/test/Integration/Truncate/Fortran/simple-no-bindc.f90 +++ b/test/Integration/Truncate/Fortran/simple-no-bindc.f90 @@ -1,3 +1,6 @@ +! ! Circumvent tests in versions where LLVM ships with a non-functional flang +! ! (see https://github.com/llvm/llvm-project/issues/138340 ) +! XFAIL: llvm-major={{21|22}} ! RUN: %flang -O1 %s -o %t.a.out %loadFlangRaptor %linkRaptorRT -lm -lmpfr && %t.a.out 100000 2 | FileCheck %s ! RUN: %flang -O2 %s -o %t.a.out %loadFlangRaptor %linkRaptorRT -lm -lmpfr && %t.a.out 100000 2 | FileCheck %s ! RUN: %flang -O3 %s -o %t.a.out %loadFlangRaptor %linkRaptorRT -lm -lmpfr && %t.a.out 100000 2 | FileCheck %s diff --git a/test/Integration/Truncate/Fortran/simple.f90 b/test/Integration/Truncate/Fortran/simple.f90 index 3befb534..a53c2831 100644 --- a/test/Integration/Truncate/Fortran/simple.f90 +++ b/test/Integration/Truncate/Fortran/simple.f90 @@ -1,3 +1,6 @@ +! ! Circumvent tests in versions where LLVM ships with a non-functional flang +! ! (see https://github.com/llvm/llvm-project/issues/138340 ) +! XFAIL: llvm-major={{21|22}} ! RUN: %flang -O0 %s -o %t.a.out %loadFlangRaptor %linkRaptorRT -lm -lmpfr && %t.a.out 100000 2 | FileCheck %s ! RUN: %flang -O1 %s -o %t.a.out %loadFlangRaptor %linkRaptorRT -lm -lmpfr && %t.a.out 100000 2 | FileCheck %s ! RUN: %flang -O2 %s -o %t.a.out %loadFlangRaptor %linkRaptorRT -lm -lmpfr && %t.a.out 100000 2 | FileCheck %s diff --git a/test/Unit/Truncate/intrinsic.ll b/test/Unit/Truncate/intrinsic.ll index 6d59328d..16d2d1a7 100644 --- a/test/Unit/Truncate/intrinsic.ll +++ b/test/Unit/Truncate/intrinsic.ll @@ -45,7 +45,7 @@ entry: ; CHECK-DAG: call double @__raptor_fprt_ieee_64_intr_llvm_pow_f64( ; CHECK-DAG: call double @__raptor_fprt_ieee_64_intr_llvm_powi_f64_i16( ; CHECK-DAG: call double @__raptor_fprt_ieee_64_binop_fadd( -; CHECK-DAG: call void @llvm.nvvm.barrier0() +; CHECK-DAG: call void @llvm.nvvm.barrier ; CHECK: define internal double @__raptor_done_truncate_op_func_ieee_64_to_ieee_32_0_0_0_f( ; CHECK-DAG: fptrunc @@ -58,4 +58,4 @@ entry: ; CHECK-DAG: call double @__raptor_fprt_ieee_64_intr_llvm_pow_f64( ; CHECK-DAG: call double @__raptor_fprt_ieee_64_intr_llvm_powi_f64_i16( ; CHECK-DAG: call double @__raptor_fprt_ieee_64_binop_fadd( -; CHECK-DAG: call void @llvm.nvvm.barrier0() +; CHECK-DAG: call void @llvm.nvvm.barrier diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in index 47597b65..6c456a51 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -44,6 +44,9 @@ except KeyError: # directories. config.excludes = ['Inputs'] +# Used when checking for major LLVM versions if tests are expected to fail +config.available_features.add('llvm-major=' + config.llvm_ver) + config.substitutions.append(('%shlibext', config.llvm_shlib_ext)) config.substitutions.append(('%lli', config.llvm_tools_dir + "/lli" + (" --jit-kind=mcjit" if int(config.llvm_ver) >= 13 else "") ))