Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -586,6 +586,9 @@ def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group; def fsignaling_math : Flag<["-"], "fsignaling-math">, Group; def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group; +def fjump_tables : Flag<["-"], "fjump-tables">, Group, + HelpText<"Use jump tables for sufficiently large switch">; +def fno_jump_tables : Flag<["-"], "fno-jump-tables">, Group, Flags<[CC1Option]>; def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group, Flags<[CC1Option, CoreOption]>, MetaVarName<"">, HelpText<"Turn on runtime checks for various forms of undefined " Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -151,6 +151,7 @@ ///< selection. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. +CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer. Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -711,6 +711,10 @@ Fn->addFnAttr(llvm::Attribute::NoInline); } + //If -fno-jump-tables pass it as Fn Attr. + if (CGM.getCodeGenOpts().NoUseJumpTables) + Fn->addFnAttr(llvm::Attribute::NoUseJumpTable); + if (getLangOpts().OpenCL) { // Add metadata for a kernel function. if (const FunctionDecl *FD = dyn_cast_or_null(D)) Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3856,6 +3856,10 @@ A->claim(); } + if (!Args.hasFlag(options::OPT_fjump_tables, options::OPT_fno_jump_tables, + true)) + CmdArgs.push_back("-fno-jump-tables"); + if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) { CmdArgs.push_back("-mregparm"); CmdArgs.push_back(A->getValue()); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -606,6 +606,8 @@ Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions); + Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables); + Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ); const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ); Opts.EmitSummaryIndex = A && A->containsValue("thin"); Index: test/CodeGen/nousejumptable.c =================================================================== --- /dev/null +++ test/CodeGen/nousejumptable.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -S -fno-jump-tables %s -emit-llvm -o - | FileCheck %s + +//CHECK: Function Attrs: nounwind nousejumptable +//CHECK-LABEL: @main() + +volatile static unsigned choice; +void ret_A(); +void ret_B(); +void ret_C(); +void ret_D(); +void ret_E(); +void ret_F(); +void ret_G(); +void ret_H(); + +int main(){ + + switch(choice){ + case 0: ret_A(); break; + case 1: ret_B(); break; + case 2: ret_C(); break; + case 3: ret_D(); break; + case 4: ret_E(); break; + case 5: ret_F(); break; + case 6: ret_G(); break; + case 7: ret_H(); break; + } + +}