diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp index 306c0ff7c704b..f0aa3f49ffaa4 100644 --- a/llvm/lib/CodeGen/CommandFlags.cpp +++ b/llvm/lib/CodeGen/CommandFlags.cpp @@ -23,6 +23,7 @@ #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -774,6 +775,25 @@ void codegen::setFunctionAttributes(Function &F, StringRef CPU, void codegen::setFunctionAttributes(Module &M, StringRef CPU, StringRef Features, StringRef TuneCPU) { + // Synthesize the "float-abi" module flag from the -float-abi option. + FloatABI::ABIType ABI = getFloatABIForCalls(); + if (ABI != FloatABI::Default) { + if (auto *Existing = + dyn_cast_or_null(M.getModuleFlag("float-abi"))) { + // The module already records a float ABI; -float-abi must not contradict + // it. + if (Existing->getString() != FloatABI::getABITypeName(ABI)) + reportFatalUsageError( + "-float-abi=" + FloatABI::getABITypeName(ABI) + + " conflicts with the \"float-abi\" module flag \"" + + Existing->getString() + "\""); + } else { + M.addModuleFlag( + Module::Error, "float-abi", + MDString::get(M.getContext(), FloatABI::getABITypeName(ABI))); + } + } + for (Function &F : M) setFunctionAttributes(F, CPU, Features, TuneCPU); } diff --git a/llvm/test/CodeGen/ARM/float-abi-module-flag.ll b/llvm/test/CodeGen/ARM/float-abi-module-flag.ll index ea57078c619bd..79e4d73cf7b1a 100644 --- a/llvm/test/CodeGen/ARM/float-abi-module-flag.ll +++ b/llvm/test/CodeGen/ARM/float-abi-module-flag.ll @@ -14,9 +14,9 @@ ; The triple default applies with no module flag. ; RUN: llc -mtriple=armv7-none-eabi -mattr=+vfp3 < %t/none.ll | FileCheck %s --check-prefix=SOFT -; An explicit module flag takes precedence over a conflicting -float-abi option. -; RUN: llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=soft < %t/hard.ll | FileCheck %s --check-prefix=HARD -; RUN: llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=hard < %t/soft.ll | FileCheck %s --check-prefix=SOFT +; A -float-abi option conflicting with the module flag is an error. +; RUN: not llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=soft < %t/hard.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT-SOFT +; RUN: not llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=hard < %t/soft.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT-HARD ;--- hard.ll define float @f(float %x) { @@ -26,6 +26,7 @@ define float @f(float %x) { !llvm.module.flags = !{!0} !0 = !{i32 1, !"float-abi", !"hard"} ; HARD: vadd.f32 s0, +; CONFLICT-SOFT: -float-abi=soft conflicts with the "float-abi" module flag "hard" ;--- soft.ll define float @f(float %x) { @@ -35,6 +36,7 @@ define float @f(float %x) { !llvm.module.flags = !{!0} !0 = !{i32 1, !"float-abi", !"soft"} ; SOFT: vmov {{s[0-9]+}}, r0 +; CONFLICT-HARD: -float-abi=hard conflicts with the "float-abi" module flag "soft" ;--- none.ll define float @f(float %x) { diff --git a/llvm/test/CodeGen/ARM/float-abi-synthesize-flag.ll b/llvm/test/CodeGen/ARM/float-abi-synthesize-flag.ll new file mode 100644 index 0000000000000..147a13b3211c5 --- /dev/null +++ b/llvm/test/CodeGen/ARM/float-abi-synthesize-flag.ll @@ -0,0 +1,36 @@ +; Check behavior of the -float-abi command-line option; it should +; synthesize the "float-abi" module flag, unless one is already +; present + +; RUN: split-file %s %t + +; -float-abi=hard writes the module flag. +; RUN: llc -mtriple=armv7-none-eabi -float-abi=hard -stop-after=finalize-isel %t/none.ll -o - | FileCheck %s --check-prefix=HARD + +; -float-abi=soft writes the module flag. +; RUN: llc -mtriple=armv7-none-eabi -float-abi=soft -stop-after=finalize-isel %t/none.ll -o - | FileCheck %s --check-prefix=SOFT + +; Without -float-abi, no flag is synthesized. +; RUN: llc -mtriple=armv7-none-eabi -stop-after=finalize-isel %t/none.ll -o - | FileCheck %s --check-prefix=NONE + +; -float-abi matching an existing in-IR flag is accepted. +; RUN: llc -mtriple=armv7-none-eabi -float-abi=hard -stop-after=finalize-isel %t/hard.ll -o - | FileCheck %s --check-prefix=HARD + +; -float-abi conflicting with an existing in-IR flag is an error. +; RUN: not llc -mtriple=armv7-none-eabi -float-abi=soft -stop-after=finalize-isel %t/hard.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT + +;--- none.ll +define void @f() { + ret void +} +; HARD: !{i32 1, !"float-abi", !"hard"} +; SOFT: !{i32 1, !"float-abi", !"soft"} +; NONE-NOT: !"float-abi" + +;--- hard.ll +define void @f() { + ret void +} +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"float-abi", !"hard"} +; CONFLICT: -float-abi=soft conflicts with the "float-abi" module flag "hard" diff --git a/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll b/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll index 78cffe05ade2f..84461789dcfa8 100644 --- a/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll +++ b/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll @@ -16,8 +16,8 @@ ; no "float-abi" flag. ; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/none.ll | FileCheck %s --check-prefix=HARD -; An explicit module flag takes precedence over the legacy -float-abi option. -; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/soft.ll | FileCheck %s --check-prefix=SOFT +; A -float-abi option conflicting with the module flag is an error. +; RUN: not llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/soft.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT ;--- none.ll define float @f(float %x, float %y) { @@ -43,3 +43,4 @@ define float @f(float %x, float %y) { ; SOFT: fmtvrl ; HARD-NOT: fmtvrl +; CONFLICT: -float-abi=hard conflicts with the "float-abi" module flag "soft"