diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -290,6 +290,7 @@ StringRef ABIName); ABI getTargetABI(StringRef ABIName); +StringRef getTargetABI(ABI ABIName); // Returns the register used to hold the stack pointer after realignment. MCRegister getBPReg(); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp @@ -75,6 +75,27 @@ return TargetABI; } +StringRef getTargetABI(ABI ABIName) { + switch (ABIName) { + default: + llvm_unreachable("Unknown ABI!"); + case ABI_ILP32: + return "ilp32"; + case ABI_ILP32F: + return "ilp32f"; + case ABI_ILP32D: + return "ilp32d"; + case ABI_ILP32E: + return "ilp32e"; + case ABI_LP64: + return "lp64"; + case ABI_LP64F: + return "lp64f"; + case ABI_LP64D: + return "lp64d"; + } +} + // To avoid the BP value clobbered by a function call, we need to choose a // callee saved register to save the value. RV32E only has X8 and X9 as callee // saved registers and X8 will be used as fp. So we choose X9 as bp. diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -91,17 +91,25 @@ // creation will depend on the TM and the code generation flags on the // function that reside in TargetOptions. resetTargetOptions(F); - auto ABIName = Options.MCOptions.getABIName(); - if (const MDString *ModuleTargetABI = dyn_cast_or_null( + + I = std::make_unique(TargetTriple, CPU, TuneCPU, FS, + Options.MCOptions.getABIName(), *this); + // The ABI should equal target-abi module flag because the different ABI + // has its corresponding datalayout and IR alignment information. In + // addition, the IR parser need to have datalayout information before it + // gets the ABI info from module. It does not make sense to update the + // module's datalayout and alignment information after IR parsing. + if (const MDString *MDModuleABI = dyn_cast_or_null( F.getParent()->getModuleFlag("target-abi"))) { - auto TargetABI = RISCVABI::getTargetABI(ABIName); - if (TargetABI != RISCVABI::ABI_Unknown && - ModuleTargetABI->getString() != ABIName) { - report_fatal_error("-target-abi option != target-abi module flag"); - } - ABIName = ModuleTargetABI->getString(); + StringRef ModuleABIName = MDModuleABI->getString(); + // Get the default ABI when target-abi option is missing. + RISCVABI::ABI TargetABI = I->getTargetABI(); + if (TargetABI != RISCVABI::getTargetABI(ModuleABIName)) + errs() << "Mismatch ABI. Currnet ABI is '" + + RISCVABI::getTargetABI(TargetABI) + + "', but IR target-abi module flag is '" + ModuleABIName + + "'.\n"; } - I = std::make_unique(TargetTriple, CPU, TuneCPU, FS, ABIName, *this); } return I.get(); } diff --git a/llvm/test/CodeGen/RISCV/module-target-abi.ll b/llvm/test/CodeGen/RISCV/module-target-abi.ll --- a/llvm/test/CodeGen/RISCV/module-target-abi.ll +++ b/llvm/test/CodeGen/RISCV/module-target-abi.ll @@ -1,20 +1,11 @@ -; RUN: llc -mtriple=riscv32 < %s 2>&1 \ -; RUN: | FileCheck -check-prefix=DEFAULT %s -; RUN: llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \ -; RUN: | FileCheck -check-prefix=RV32IF-ILP32 %s -; RUN: not --crash llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \ -; RUN: | FileCheck -check-prefix=RV32IF-ILP32F %s -; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s +; Default rv32 ABI is ilp32 which equals target-abi module flag, so the result is correct. +; RUN: llc -mtriple=riscv32 < %s -o /dev/null +; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s -o /dev/null 2>&1 \ +; RUN: | FileCheck %s -; RV32IF-ILP32F: -target-abi option != target-abi module flag - -; FLAGS: Flags: 0x0 +; CHECK: Mismatch ABI. Currnet ABI is 'ilp32f', but IR target-abi module flag is 'ilp32'. define float @foo(i32 %a) nounwind #0 { -; DEFAULT: # %bb.0: -; DEFAULT: fmv.x.w a0, ft0 -; RV32IF-ILP32: # %bb.0: -; RV32IF-ILP32: fmv.x.w a0, ft0 %conv = sitofp i32 %a to float ret float %conv } diff --git a/llvm/test/CodeGen/RISCV/module-target-abi2.ll b/llvm/test/CodeGen/RISCV/module-target-abi2.ll --- a/llvm/test/CodeGen/RISCV/module-target-abi2.ll +++ b/llvm/test/CodeGen/RISCV/module-target-abi2.ll @@ -1,23 +1,11 @@ -; RUN: llc -mtriple=riscv32 < %s 2>&1 \ -; RUN: | FileCheck -check-prefix=DEFAULT %s -; RUN: not --crash llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \ -; RUN: | FileCheck -check-prefix=RV32IF-ILP32 %s -; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \ -; RUN: | FileCheck -check-prefix=RV32IF-ILP32F %s -; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s +; Default rv32 ABI is ilp32 which mismatch with target-abi module flag ilp32f +; RUN: llc -mtriple=riscv32 < %s -o /dev/null 2>&1 | FileCheck %s +; RUN: llc -mtriple=riscv32 -target-abi ilp32 < %s -o /dev/null 2>&1 \ +; RUN: | FileCheck %s -; RV32IF-ILP32: -target-abi option != target-abi module flag - -; FLAGS: Flags: 0x0 -; // this should be "Flags :0x2, single-float ABI", it will be fixed later. +; CHECK: Mismatch ABI. Currnet ABI is 'ilp32', but IR target-abi module flag is 'ilp32f'. define float @foo(i32 %a) nounwind #0 { -; DEFAULT: # %bb.0: -; DEFAULT-NEXT: fcvt.s.w fa0, a0 -; DEFAULT-NEXT: ret -; RV32IF-ILP32F: # %bb.0: -; RV32IF-ILP32F: fcvt.s.w fa0, a0 -; RV32IF-ILP32F: ret %conv = sitofp i32 %a to float ret float %conv }