Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1102,6 +1102,10 @@ Alias, AliasArgs<["full"]>, HelpText<"Enable cf-protection in 'full' mode">; +def fexperimental_use_cond_trap : Flag<["-"], "fexperimental-use-cond-trap">, + Group, Flags<[CC1Option]>, + HelpText<"Enables an experimental conditional trap in LLVM.">; + def fxray_instrument : Flag<["-"], "fxray-instrument">, Group, Flags<[CC1Option]>, HelpText<"Generate XRay instrumentation sleds on function entry and exit">; @@ -1437,6 +1441,10 @@ def : Flag<["-"], "fno-aligned-new">, Alias; def faligned_new_EQ : Joined<["-"], "faligned-new=">; +def fno_experimental_use_cond_trap : Flag<["-"], "fno-experimental-use-cond-trap">, + Group, Flags<[CC1Option]>, + HelpText<"Disables an experimental conditional trap in LLVM.">; + def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group; def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group; def fobjc_infer_related_result_type : Flag<["-"], "fobjc-infer-related-result-type">, Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -332,6 +332,8 @@ /// Whether to embed source in DWARF debug line section. CODEGENOPT(EmbedSource, 1, 0) +CODEGENOPT(ExperimentalUseCondTrap, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3131,18 +3131,25 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) { llvm::BasicBlock *Cont = createBasicBlock("cont"); - // If we're optimizing, collapse all calls to trap down to just one per - // function to save on code size. - if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) { - TrapBB = createBasicBlock("trap"); + if (CGM.getCodeGenOpts().ExperimentalUseCondTrap) { + TrapBB = createBasicBlock("condtrap"); Builder.CreateCondBr(Checked, Cont, TrapBB); EmitBlock(TrapBB); - llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); - TrapCall->setDoesNotReturn(); - TrapCall->setDoesNotThrow(); - Builder.CreateUnreachable(); + Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::condtrap)); } else { - Builder.CreateCondBr(Checked, Cont, TrapBB); + // If we're optimizing, collapse all calls to trap down to just one per + // function to save on code size. + if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) { + TrapBB = createBasicBlock("trap"); + Builder.CreateCondBr(Checked, Cont, TrapBB); + EmitBlock(TrapBB); + llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); + TrapCall->setDoesNotReturn(); + TrapCall->setDoesNotThrow(); + Builder.CreateUnreachable(); + } else { + Builder.CreateCondBr(Checked, Cont, TrapBB); + } } EmitBlock(Cont); Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -4799,6 +4799,9 @@ CmdArgs.push_back("-fforce-enable-int128"); } + Args.AddLastArg(CmdArgs, options::OPT_fexperimental_use_cond_trap, + options::OPT_fno_experimental_use_cond_trap); + // Finally add the compile command to the compilation. if (Args.hasArg(options::OPT__SLASH_fallback) && Output.getType() == types::TY_Object && Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1118,6 +1118,10 @@ Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); + Opts.ExperimentalUseCondTrap = Args.hasFlag( + OPT_fexperimental_use_cond_trap, OPT_fno_experimental_use_cond_trap, + /* Default */ false); + return Success; }