Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -3146,6 +3146,10 @@ HelpText<"Enable using library calls for save and restore">; def mno_save_restore : Flag<["-"], "mno-save-restore">, Group, HelpText<"Disable using library calls for save and restore">; +def mno_div : Flag<["-"], "mno-div">, Group, + HelpText<"Disable integer division instructions in M extension">; +def mdiv : Flag<["-"], "mdiv">, Group, + HelpText<"Enable integer division instructions in M extension">; def mcmodel_EQ_medlow : Flag<["-"], "mcmodel=medlow">, Group, Flags<[CC1Option]>, Alias, AliasArgs<["small"]>, HelpText<"Equivalent to -mcmodel=small, compatible with RISC-V gcc.">; Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -572,6 +572,15 @@ // Now add any that the user explicitly requested on the command line, // which may override the defaults. handleTargetFeaturesGroup(Args, Features, options::OPT_m_riscv_Features_Group); + + bool noDiv = Args.hasFlag(options::OPT_mno_div, options::OPT_mdiv, false); + for (auto &Feature : Features) { + if (noDiv && (Feature == "+m" || Feature == "-div")) { + Feature = "+experimental-zmmul"; + } else if (Feature == "+div") { + Feature = "+m"; + } + } } StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) { Index: clang/test/Driver/riscv-no-div.c =================================================================== --- /dev/null +++ clang/test/Driver/riscv-no-div.c @@ -0,0 +1,30 @@ +// RUN: %clang -target riscv32-unknown-elf %s -mno-div -S -o - 2>&1 \ +// RUN: | not FileCheck -check-prefix=CHECK-DIV %s + +// RUN: %clang -target riscv64-unknown-elf %s -mno-div -S -o - 2>&1 \ +// RUN: | not FileCheck -check-prefix=CHECK-DIV %s + +// RUN: %clang -target riscv32-unknown-elf %s -mno-div -S -o - 2>&1 \ +// RUN: | not FileCheck -check-prefix=CHECK-REM %s + +// RUN: %clang -target riscv64-unknown-elf %s -mno-div -S -o - 2>&1 \ +// RUN: | not FileCheck -check-prefix=CHECK-REM %s + +// RUN: %clang -target riscv32-unknown-elf %s -mno-div -S -o - 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-MUL %s + +// RUN: %clang -target riscv64-unknown-elf %s -mno-div -S -o - 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-MUL %s + +// RUN: %clang -target riscv32-unknown-elf %s -S -o - 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK-MUL,CHECK-DIV,CHECK-REM %s + +// RUN: %clang -target riscv64-unknown-elf %s -S -o - 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK-MUL,CHECK-DIV,CHECK-REM %s + +int foo(int x, int y) { + // CHECK-DIV: div{{w?}} a{{[0-9]}}, a{{[0-9]}}, a{{[0-9]}} + // CHECK-REM: rem{{w?}} a{{[0-9]}}, a{{[0-9]}}, a{{[0-9]}} + // CHECK-MUL: mul{{w?}} a{{[0-9]}}, a{{[0-9]}}, a{{[0-9]}} + return (x / y) * (x % y); +}