diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -541,3 +541,14 @@ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-D-ZDINX-ER %s // RV32-D-ZDINX-ER: error: invalid arch name 'rv32idzdinx', // RV32-D-ZFINX-ER: 'f' and 'zfinx' extensions are incompatible + +// RUN: %clang --target=riscv32-unknown-elf -march=rv32ef -### %s \ +// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EF-BADVARS %s +// RV32-EF-BADVARS: error: invalid arch name 'rv32ef', +// RV32-EF-BADVARS: 'e' extension is incompatible with 'f' extension + +// RUN: %clang --target=riscv32-unknown-elf -march=rv32ed -### %s \ +// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-ED-BADVARS %s +// RV32-ED-BADVARS: error: invalid arch name 'rv32ed', +// RV32-ED-BADVARS: 'e' extension is incompatible with 'f' extension and 'd' extension + diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -895,6 +895,7 @@ Error RISCVISAInfo::checkDependency() { bool HasC = Exts.count("c") != 0; bool HasF = Exts.count("f") != 0; + bool HasD = Exts.count("d") != 0; bool HasZfinx = Exts.count("zfinx") != 0; bool HasVector = Exts.count("zve32x") != 0; bool HasZvl = MinVLen != 0; @@ -931,7 +932,7 @@ errc::invalid_argument, "'zvknhb' requires 'v' or 'zve64*' extension to also be specified"); - if ((HasZcmt || Exts.count("zcmp")) && Exts.count("d") && + if ((HasZcmt || Exts.count("zcmp")) && HasD && (HasC || Exts.count("zcd"))) return createStringError( errc::invalid_argument, @@ -944,8 +945,17 @@ "'zcf' is only supported for 'rv32'"); // Additional dependency checks. - // TODO: The 'q' extension requires rv64. - // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'. + // The 'q' extension requires rv64. + if (XLen != 64 && Exts.count("q")) + return createStringError(errc::invalid_argument, + "'q' extension is only supported for 'rv64'"); + + // It is illegal to specify 'e' extensions with 'f' and 'd'. + if (Exts.count("e") && (HasF || HasD)) + return createStringError( + errc::invalid_argument, + Twine("'e' extension is incompatible with ") + + (HasD ? "'f' extension and 'd' extension" : "'f' extension")); return Error::success(); } diff --git a/llvm/test/MC/RISCV/target-abi-invalid.s b/llvm/test/MC/RISCV/target-abi-invalid.s --- a/llvm/test/MC/RISCV/target-abi-invalid.s +++ b/llvm/test/MC/RISCV/target-abi-invalid.s @@ -28,10 +28,6 @@ # RUN: | FileCheck -check-prefix=RV32IFD-LP64D %s # RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64 < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32E-LP64 %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV32EF-LP64F %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV32EFD-LP64D %s # RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64e %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32E-LP64E %s @@ -39,8 +35,6 @@ # RV32IF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) # RV32IFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) # RV32E-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32EF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32EFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) # RV32E-LP64E: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) # RUN: llvm-mc -triple=riscv32 -target-abi ilp32f < %s 2>&1 \ @@ -66,31 +60,13 @@ # RV64IF-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) # RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi ilp32 < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV32EF-ILP32F %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi ilp32f < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV32EF-ILP32F %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32f < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV32EFD-ILP32F %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32d < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV32EFD-ILP32D %s +# RUN: | FileCheck -check-prefix=RV32E-ILP32 %s # RV32E-ILP32: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EF-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EFD-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EFD-ILP32D: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) # RUN: llvm-mc -triple=riscv64 -mattr=+e -target-abi lp64 < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV64EF-LP64F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV64EF-LP64F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV64EFD-LP64F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64d < %s 2>&1 \ -# RUN: | FileCheck -check-prefix=RV64EFD-LP64D %s +# RUN: | FileCheck -check-prefix=RV64E-LP64 %s # RV64E-LP64: Only the lp64e ABI is supported for RV64E (ignoring target-abi) -# RV64EF-LP64F: Only the lp64e ABI is supported for RV64E (ignoring target-abi) -# RV64EFD-LP64F: Only the lp64e ABI is supported for RV64E (ignoring target-abi) -# RV64EFD-LP64D: Only the lp64e ABI is supported for RV64E (ignoring target-abi) nop diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -474,6 +474,17 @@ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), "'zcf' is only supported for 'rv32'"); } + + for (StringRef Input : {"rv64efd", "rv32efd", "rv64ed", "rv32ed"}) { + EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), + "'e' extension is incompatible with 'f' extension" + " and 'd' extension"); + } + + for (StringRef Input : {"rv64ef", "rv32ef"}) { + EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), + "'e' extension is incompatible with 'f' extension"); + } } TEST(ToFeatureVector, IIsDroppedAndExperimentalExtensionsArePrefixed) {