Index: include/clang/Driver/Driver.h =================================================================== --- include/clang/Driver/Driver.h +++ include/clang/Driver/Driver.h @@ -359,8 +359,11 @@ /// \param C - The compilation that is being built. /// \param Args - The input arguments. /// \param Actions - The list to store the resulting actions onto. + /// \param MultiArchUniversalBuild - Whether a universal build for multiple + /// architectures is being performed. void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, - const InputList &Inputs, ActionList &Actions) const; + const InputList &Inputs, ActionList &Actions, + bool MultiArchUniversalBuild) const; /// BuildUniversalActions - Construct the list of actions to perform /// for the given arguments, which may require a universal build. Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -707,7 +707,7 @@ if (TC.getTriple().isOSBinFormatMachO()) BuildUniversalActions(*C, C->getDefaultToolChain(), Inputs); else - BuildActions(*C, C->getArgs(), Inputs, C->getActions()); + BuildActions(*C, C->getArgs(), Inputs, C->getActions(), false); if (CCCPrintPhases) { PrintActions(*C); @@ -910,7 +910,7 @@ if (TC.getTriple().isOSBinFormatMachO()) BuildUniversalActions(C, TC, Inputs); else - BuildActions(C, C.getArgs(), Inputs, C.getActions()); + BuildActions(C, C.getArgs(), Inputs, C.getActions(), false); BuildJobs(C); @@ -1392,7 +1392,7 @@ Archs.push_back(Args.MakeArgString(TC.getDefaultUniversalArchName())); ActionList SingleActions; - BuildActions(C, Args, BAInputs, SingleActions); + BuildActions(C, Args, BAInputs, SingleActions, Archs.size() > 1); // Add in arch bindings for every top level action, as well as lipo and // dsymutil steps if needed. @@ -2389,7 +2389,8 @@ } // anonymous namespace. void Driver::BuildActions(Compilation &C, DerivedArgList &Args, - const InputList &Inputs, ActionList &Actions) const { + const InputList &Inputs, ActionList &Actions, + bool MultiArchUniversalBuild) const { llvm::PrettyStackTraceString CrashInfo("Building compilation actions"); if (!SuppressMissingInputWarning && Inputs.empty()) { @@ -2595,6 +2596,22 @@ break; } + // When saving temps, add extra actions to write unoptimized and optimized + // IR besides the normal bitcode outputs if possible. This is not possible + // for Mach-O multi-arch universal builds because in these builds we check + // that we can lipo all action outputs, and types::TY_LLVM_IR is not + // lipo-able. + if (!MultiArchUniversalBuild) { + if (isSaveTempsEnabled() && Phase == phases::Compile) { + Actions.push_back( + C.MakeAction(Current, types::TY_LLVM_IR)); + } + if (isSaveTempsEnabled() && Phase == phases::Backend) { + Actions.push_back( + C.MakeAction(Current, types::TY_LLVM_IR)); + } + } + // Otherwise construct the appropriate action. auto *NewCurrent = ConstructPhaseAction(C, Args, Phase, Current); @@ -3544,6 +3561,11 @@ if (!AtTopLevel && C.getArgs().hasArg(options::OPT_emit_llvm) && JA.getType() == types::TY_LLVM_BC) Suffixed += ".tmp"; + // When using -save-temps, append a ".unoptimized" suffix so that the + // optimized .ll file doesn't overwrite the unoptimized one. + if (isSaveTempsEnabled() && JA.getType() == types::TY_LLVM_IR && + JA.getKind() == Action::CompileJobClass) + Suffixed += ".unoptimized"; Suffixed += '.'; Suffixed += Suffix; NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str()); Index: test/Driver/cuda-options.cu =================================================================== --- test/Driver/cuda-options.cu +++ test/Driver/cuda-options.cu @@ -151,6 +151,12 @@ // NOARCH-SM35-NOT: "-cc1"{{.*}}"-target-cpu" "sm_35" // ARCHALLERROR: error: Unsupported CUDA gpu architecture: all +// Match host-side preprocessor job with -save-temps. +// HOST-SAVE: "-cc1" "-triple" "x86_64--linux-gnu" +// HOST-SAVE-SAME: "-aux-triple" "nvptx64-nvidia-cuda" +// HOST-SAVE-NOT: "-fcuda-is-device" +// HOST-SAVE-SAME: "-x" "cuda" + // Match device-side preprocessor and compiler phases with -save-temps. // DEVICE-SAVE: "-cc1" "-triple" "nvptx64-nvidia-cuda" // DEVICE-SAVE-SAME: "-aux-triple" "x86_64--linux-gnu" @@ -194,12 +200,6 @@ // INCLUDES-DEVICE-DAG: "--image=profile=sm_{{[0-9]+}},file=[[CUBINFILE]]" // INCLUDES-DEVICE-DAG: "--image=profile=compute_{{[0-9]+}},file=[[PTXFILE]]" -// Match host-side preprocessor job with -save-temps. -// HOST-SAVE: "-cc1" "-triple" "x86_64--linux-gnu" -// HOST-SAVE-SAME: "-aux-triple" "nvptx64-nvidia-cuda" -// HOST-SAVE-NOT: "-fcuda-is-device" -// HOST-SAVE-SAME: "-x" "cuda" - // Match host-side compilation. // HOST: "-cc1" "-triple" "x86_64--linux-gnu" // HOST-SAME: "-aux-triple" "nvptx64-nvidia-cuda" Index: test/Driver/save-temps.c =================================================================== --- test/Driver/save-temps.c +++ test/Driver/save-temps.c @@ -1,9 +1,11 @@ // RUN: %clang -target x86_64-apple-darwin -save-temps -arch x86_64 %s -### 2>&1 \ // RUN: | FileCheck %s // CHECK: "-o" "save-temps.i" +// CHECK: "-o" "save-temps.unoptimized.ll" // CHECK: "-emit-llvm-uselists" // CHECK: "-disable-llvm-passes" // CHECK: "-o" "save-temps.bc" +// CHECK: "-o" "save-temps.ll" // CHECK: "-o" "save-temps.s" // CHECK: "-o" "save-temps.o" // CHECK: "-o" "a.out"