From f616b66fe7d1e9dcaadda2b21c4d69198f2de304 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Mon, 6 Jan 2025 14:13:21 -0600 Subject: [PATCH] [NVPTX] Do not run the NVVMReflect pass as part of the normal pipeline Summary: This pass lowers the `__nvvm_reflect` builtin in the IR. However, this currently runs in the standard optimization pipeline, not just the backend pipeline. This means that if the user creates LLVM-IR without an architecture set, it will always delete the reflect code even if it is intended to be used later. Pushing this into the backend pipeline will ensure that this works as intended, allowing users to conditionally include code depending on which target architecture the user ended up using. This fixes a bug in OpenMP and missing code in `libc`. --- llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 1 - llvm/lib/Target/NVPTX/NVVMReflect.cpp | 8 +++++++- llvm/test/CodeGen/NVPTX/nvvm-reflect-arch.ll | 4 ++-- llvm/test/CodeGen/NVPTX/nvvm-reflect-ocl.ll | 4 ++-- llvm/test/CodeGen/NVPTX/nvvm-reflect-opaque.ll | 6 +++--- llvm/test/CodeGen/NVPTX/nvvm-reflect.ll | 7 ++++--- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp index b3b2880588cc59..f6ec780d963d9a 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -255,7 +255,6 @@ void NVPTXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { PB.registerPipelineStartEPCallback( [this](ModulePassManager &PM, OptimizationLevel Level) { FunctionPassManager FPM; - FPM.addPass(NVVMReflectPass(Subtarget.getSmVersion())); // Note: NVVMIntrRangePass was causing numerical discrepancies at one // point, if issues crop up, consider disabling. FPM.addPass(NVVMIntrRangePass()); diff --git a/llvm/lib/Target/NVPTX/NVVMReflect.cpp b/llvm/lib/Target/NVPTX/NVVMReflect.cpp index 56525a1edc7614..a0e897584a9d32 100644 --- a/llvm/lib/Target/NVPTX/NVVMReflect.cpp +++ b/llvm/lib/Target/NVPTX/NVVMReflect.cpp @@ -21,6 +21,7 @@ #include "NVPTX.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" @@ -219,7 +220,12 @@ bool NVVMReflect::runOnFunction(Function &F) { return runNVVMReflect(F, SmVersion); } -NVVMReflectPass::NVVMReflectPass() : NVVMReflectPass(0) {} +NVVMReflectPass::NVVMReflectPass() { + // Get the CPU string from the command line if not provided. + StringRef SM = codegen::getMCPU(); + if (!SM.consume_front("sm_") || SM.consumeInteger(10, SmVersion)) + SmVersion = 0; +} PreservedAnalyses NVVMReflectPass::run(Function &F, FunctionAnalysisManager &AM) { diff --git a/llvm/test/CodeGen/NVPTX/nvvm-reflect-arch.ll b/llvm/test/CodeGen/NVPTX/nvvm-reflect-arch.ll index ac5875c6ab1043..83cb3cde48de18 100644 --- a/llvm/test/CodeGen/NVPTX/nvvm-reflect-arch.ll +++ b/llvm/test/CodeGen/NVPTX/nvvm-reflect-arch.ll @@ -1,9 +1,9 @@ ; Libdevice in recent CUDA versions relies on __CUDA_ARCH reflecting GPU type. ; Verify that __nvvm_reflect() is replaced with an appropriate value. ; -; RUN: opt %s -S -passes='default' -mtriple=nvptx64 -mcpu=sm_20 \ +; RUN: opt %s -S -passes='nvvm-reflect' -mtriple=nvptx64 -mcpu=sm_20 \ ; RUN: | FileCheck %s --check-prefixes=COMMON,SM20 -; RUN: opt %s -S -passes='default' -mtriple=nvptx64 -mcpu=sm_35 \ +; RUN: opt %s -S -passes='nvvm-reflect' -mtriple=nvptx64 -mcpu=sm_35 \ ; RUN: | FileCheck %s --check-prefixes=COMMON,SM35 @"$str" = private addrspace(1) constant [12 x i8] c"__CUDA_ARCH\00" diff --git a/llvm/test/CodeGen/NVPTX/nvvm-reflect-ocl.ll b/llvm/test/CodeGen/NVPTX/nvvm-reflect-ocl.ll index 9d383218dce86a..bf8d6e2cca3071 100644 --- a/llvm/test/CodeGen/NVPTX/nvvm-reflect-ocl.ll +++ b/llvm/test/CodeGen/NVPTX/nvvm-reflect-ocl.ll @@ -1,8 +1,8 @@ ; Verify that __nvvm_reflect_ocl() is replaced with an appropriate value ; -; RUN: opt %s -S -passes='default' -mtriple=nvptx64 -mcpu=sm_20 \ +; RUN: opt %s -S -passes='nvvm-reflect' -mtriple=nvptx64 -mcpu=sm_20 \ ; RUN: | FileCheck %s --check-prefixes=COMMON,SM20 -; RUN: opt %s -S -passes='default' -mtriple=nvptx64 -mcpu=sm_35 \ +; RUN: opt %s -S -passes='nvvm-reflect' -mtriple=nvptx64 -mcpu=sm_35 \ ; RUN: | FileCheck %s --check-prefixes=COMMON,SM35 @"$str" = private addrspace(4) constant [12 x i8] c"__CUDA_ARCH\00" diff --git a/llvm/test/CodeGen/NVPTX/nvvm-reflect-opaque.ll b/llvm/test/CodeGen/NVPTX/nvvm-reflect-opaque.ll index 46ab79d9858cad..19c74df3037028 100644 --- a/llvm/test/CodeGen/NVPTX/nvvm-reflect-opaque.ll +++ b/llvm/test/CodeGen/NVPTX/nvvm-reflect-opaque.ll @@ -3,12 +3,12 @@ ; RUN: cat %s > %t.noftz ; RUN: echo '!0 = !{i32 4, !"nvvm-reflect-ftz", i32 0}' >> %t.noftz -; RUN: opt %t.noftz -S -mtriple=nvptx-nvidia-cuda -passes='default' \ +; RUN: opt %t.noftz -S -mtriple=nvptx-nvidia-cuda -passes='nvvm-reflect,simplifycfg' \ ; RUN: | FileCheck %s --check-prefix=USE_FTZ_0 --check-prefix=CHECK ; RUN: cat %s > %t.ftz ; RUN: echo '!0 = !{i32 4, !"nvvm-reflect-ftz", i32 1}' >> %t.ftz -; RUN: opt %t.ftz -S -mtriple=nvptx-nvidia-cuda -passes='default' \ +; RUN: opt %t.ftz -S -mtriple=nvptx-nvidia-cuda -passes='nvvm-reflect,simplifycfg' \ ; RUN: | FileCheck %s --check-prefix=USE_FTZ_1 --check-prefix=CHECK @str = private unnamed_addr addrspace(4) constant [11 x i8] c"__CUDA_FTZ\00" @@ -43,7 +43,7 @@ exit: declare i32 @llvm.nvvm.reflect(ptr) -; CHECK-LABEL: define noundef i32 @intrinsic +; CHECK-LABEL: define i32 @intrinsic define i32 @intrinsic() { ; CHECK-NOT: call i32 @llvm.nvvm.reflect ; USE_FTZ_0: ret i32 0 diff --git a/llvm/test/CodeGen/NVPTX/nvvm-reflect.ll b/llvm/test/CodeGen/NVPTX/nvvm-reflect.ll index 2ed9f7c11bcf9b..244b44fea9b83c 100644 --- a/llvm/test/CodeGen/NVPTX/nvvm-reflect.ll +++ b/llvm/test/CodeGen/NVPTX/nvvm-reflect.ll @@ -3,12 +3,12 @@ ; RUN: cat %s > %t.noftz ; RUN: echo '!0 = !{i32 4, !"nvvm-reflect-ftz", i32 0}' >> %t.noftz -; RUN: opt %t.noftz -S -mtriple=nvptx-nvidia-cuda -passes='default' \ +; RUN: opt %t.noftz -S -mtriple=nvptx-nvidia-cuda -passes='nvvm-reflect,simplifycfg' \ ; RUN: | FileCheck %s --check-prefix=USE_FTZ_0 --check-prefix=CHECK ; RUN: cat %s > %t.ftz ; RUN: echo '!0 = !{i32 4, !"nvvm-reflect-ftz", i32 1}' >> %t.ftz -; RUN: opt %t.ftz -S -mtriple=nvptx-nvidia-cuda -passes='default' \ +; RUN: opt %t.ftz -S -mtriple=nvptx-nvidia-cuda -passes='nvvm-reflect,simplifycfg' \ ; RUN: | FileCheck %s --check-prefix=USE_FTZ_1 --check-prefix=CHECK @str = private unnamed_addr addrspace(4) constant [11 x i8] c"__CUDA_FTZ\00" @@ -43,7 +43,8 @@ exit: declare i32 @llvm.nvvm.reflect(ptr) -; CHECK-LABEL: define noundef i32 @intrinsic +; CHECK-LABEL: define i32 @intrinsic + define i32 @intrinsic() { ; CHECK-NOT: call i32 @llvm.nvvm.reflect ; USE_FTZ_0: ret i32 0