r340681 - [CUDA/OpenMP] Define only some host macros during device compilation

Jonas Hahnfeld via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 25 06:42:40 PDT 2018


Author: hahnfeld
Date: Sat Aug 25 06:42:40 2018
New Revision: 340681

URL: http://llvm.org/viewvc/llvm-project?rev=340681&view=rev
Log:
[CUDA/OpenMP] Define only some host macros during device compilation

When compiling CUDA or OpenMP device code Clang parses header files
that expect certain predefined macros from the host architecture. To
make this work the compiler passes the host triple via the -aux-triple
argument and (until now) pulls in all macros for that "auxiliary triple"
unconditionally.

However this results in defines like __SSE_MATH__ that will trigger
inline assembly making use of the "advertised" target features. See
the discussion of D47849 and PR38464 for a detailed explanation of
the encountered problems.

Instead of blacklisting "known bad" examples this patch starts adding
defines that are needed for certain headers like bits/wordsize.h and
bits/mathinline.h.
The disadvantage of this approach is that it decouples the definitions
from their target toolchain. However in my opinion it's more important
to keep definitions for one header close together. For one this will
include a clear documentation why these particular defines are needed.
Furthermore it simplifies maintenance because adding defines for a new
header or support for a new aux-triple only needs to touch one piece
of code.

Differential Revision: https://reviews.llvm.org/D50845

Added:
    cfe/trunk/test/Preprocessor/aux-triple.c
Modified:
    cfe/trunk/lib/Frontend/InitPreprocessor.cpp
    cfe/trunk/test/SemaCUDA/builtins.cu

Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=340681&r1=340680&r2=340681&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Sat Aug 25 06:42:40 2018
@@ -1099,6 +1099,44 @@ static void InitializePredefinedMacros(c
   TI.getTargetDefines(LangOpts, Builder);
 }
 
+/// Initialize macros based on AuxTargetInfo.
+static void InitializePredefinedAuxMacros(const TargetInfo &AuxTI,
+                                          const LangOptions &LangOpts,
+                                          MacroBuilder &Builder) {
+  auto AuxTriple = AuxTI.getTriple();
+
+  // Define basic target macros needed by at least bits/wordsize.h and
+  // bits/mathinline.h
+  switch (AuxTriple.getArch()) {
+  case llvm::Triple::x86_64:
+    Builder.defineMacro("__x86_64__");
+    break;
+  case llvm::Triple::ppc64:
+  case llvm::Triple::ppc64le:
+    Builder.defineMacro("__powerpc64__");
+    break;
+  default:
+    break;
+  }
+
+  // libc++ needs to find out the object file format and threading API.
+  if (AuxTriple.getOS() == llvm::Triple::Linux) {
+    Builder.defineMacro("__ELF__");
+    Builder.defineMacro("__linux__");
+    // Used in features.h. If this is omitted, math.h doesn't declare float
+    // versions of the functions in bits/mathcalls.h.
+    if (LangOpts.CPlusPlus)
+      Builder.defineMacro("_GNU_SOURCE");
+  } else if (AuxTriple.isOSDarwin()) {
+    Builder.defineMacro("__APPLE__");
+    Builder.defineMacro("__MACH__");
+  } else if (AuxTriple.isOSWindows()) {
+    Builder.defineMacro("_WIN32");
+    if (AuxTriple.isWindowsGNUEnvironment())
+      Builder.defineMacro("__MINGW32__");
+  }
+}
+
 /// InitializePreprocessor - Initialize the preprocessor getting it and the
 /// environment ready to process a single file. This returns true on error.
 ///
@@ -1120,13 +1158,9 @@ void clang::InitializePreprocessor(
 
   // Install things like __POWERPC__, __GNUC__, etc into the macro table.
   if (InitOpts.UsePredefines) {
-    // FIXME: This will create multiple definitions for most of the predefined
-    // macros. This is not the right way to handle this.
-    if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice) && PP.getAuxTargetInfo())
-      InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
-                                 Builder);
-
     InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts, Builder);
+    if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice) && PP.getAuxTargetInfo())
+      InitializePredefinedAuxMacros(*PP.getAuxTargetInfo(), LangOpts, Builder);
 
     // Install definitions to make Objective-C++ ARC work well with various
     // C++ Standard Library implementations.

Added: cfe/trunk/test/Preprocessor/aux-triple.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/aux-triple.c?rev=340681&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/aux-triple.c (added)
+++ cfe/trunk/test/Preprocessor/aux-triple.c Sat Aug 25 06:42:40 2018
@@ -0,0 +1,62 @@
+// Ensure that Clang sets some very basic target defines based on -aux-triple.
+
+// RUN: %clang_cc1 -E -dM -ffreestanding < /dev/null \
+// RUN:     -triple nvptx64-none-none \
+// RUN:   | FileCheck -match-full-lines -check-prefixes NVPTX64,NONE %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding < /dev/null \
+// RUN:     -triple nvptx64-none-none \
+// RUN:   | FileCheck -match-full-lines -check-prefixes NVPTX64,NONE %s
+// RUN: %clang_cc1 -x cuda -E -dM -ffreestanding < /dev/null \
+// RUN:     -triple nvptx64-none-none \
+// RUN:   | FileCheck -match-full-lines -check-prefixes NVPTX64,NONE %s
+
+// CUDA:
+// RUN: %clang_cc1 -x cuda -E -dM -ffreestanding < /dev/null \
+// RUN:     -triple nvptx64-none-none -aux-triple powerpc64le-unknown-linux-gnu \
+// RUN:   | FileCheck -match-full-lines %s \
+// RUN:     -check-prefixes NVPTX64,PPC64,LINUX,LINUX-CPP
+// RUN: %clang_cc1 -x cuda -E -dM -ffreestanding < /dev/null \
+// RUN:     -triple nvptx64-none-none -aux-triple x86_64-unknown-linux-gnu \
+// RUN:   | FileCheck -match-full-lines %s \
+// RUN:     -check-prefixes NVPTX64,X86_64,LINUX,LINUX-CPP
+
+// OpenMP:
+// RUN: %clang_cc1 -E -dM -ffreestanding < /dev/null \
+// RUN:     -fopenmp -fopenmp-is-device -triple nvptx64-none-none \
+// RUN:     -aux-triple powerpc64le-unknown-linux-gnu \
+// RUN:   | FileCheck -match-full-lines -check-prefixes NVPTX64,PPC64,LINUX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding < /dev/null \
+// RUN:     -fopenmp -fopenmp-is-device -triple nvptx64-none-none \
+// RUN:     -aux-triple x86_64-unknown-linux-gnu \
+// RUN:   | FileCheck -match-full-lines -check-prefixes NVPTX64,X86_64,LINUX %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding < /dev/null \
+// RUN:     -fopenmp -fopenmp-is-device -triple nvptx64-none-none \
+// RUN:     -aux-triple powerpc64le-unknown-linux-gnu \
+// RUN:   | FileCheck -match-full-lines %s \
+// RUN:     -check-prefixes NVPTX64,PPC64,LINUX,LINUX-CPP
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding < /dev/null \
+// RUN:     -fopenmp -fopenmp-is-device -triple nvptx64-none-none \
+// RUN:     -aux-triple x86_64-unknown-linux-gnu \
+// RUN:   | FileCheck -match-full-lines %s \
+// RUN:     -check-prefixes NVPTX64,X86_64,LINUX,LINUX-CPP
+
+// NONE-NOT:#define _GNU_SOURCE
+// LINUX-CPP:#define _GNU_SOURCE 1
+
+// NVPTX64:#define _LP64 1
+
+// NONE-NOT:#define __ELF__
+// LINUX:#define __ELF__ 1
+
+// NVPTX64:#define __LP64__ 1
+// NVPTX64:#define __NVPTX__ 1
+// NVPTX64:#define __PTX__ 1
+
+// NONE-NOT:#define __linux__
+// LINUX:#define __linux__ 1
+
+// NONE-NOT:#define __powerpc64__
+// PPC64:#define __powerpc64__ 1
+
+// NONE-NOT:#define __x86_64__
+// X86_64:#define __x86_64__ 1

Modified: cfe/trunk/test/SemaCUDA/builtins.cu
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCUDA/builtins.cu?rev=340681&r1=340680&r2=340681&view=diff
==============================================================================
--- cfe/trunk/test/SemaCUDA/builtins.cu (original)
+++ cfe/trunk/test/SemaCUDA/builtins.cu Sat Aug 25 06:42:40 2018
@@ -12,8 +12,8 @@
 // RUN:     -aux-triple x86_64-unknown-unknown \
 // RUN:     -fsyntax-only -verify %s
 
-#if !(defined(__amd64__) && defined(__PTX__))
-#error "Expected to see preprocessor macros from both sides of compilation."
+#if !defined(__x86_64__)
+#error "Expected to see preprocessor macros from the host."
 #endif
 
 void hf() {




More information about the cfe-commits mailing list