Index: include/llvm/Target/TargetLowering.h =================================================================== --- include/llvm/Target/TargetLowering.h +++ include/llvm/Target/TargetLowering.h @@ -1235,11 +1235,10 @@ HasExtractBitsInsn = hasExtractInsn; } - /// Tells the code generator not to expand sequence of operations into a - /// separate sequences that increases the amount of flow control. - void setJumpIsExpensive(bool isExpensive = true) { - JumpIsExpensive = isExpensive; - } + /// Tells the code generator not to expand logic operations on comparison + /// predicates into separate sequences that increase the amount of flow + /// control. + void setJumpIsExpensive(bool isExpensive = true); /// Tells the code generator that integer divide is expensive, and if /// possible, should be replaced by an alternate sequence of instructions not Index: lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- lib/CodeGen/TargetLoweringBase.cpp +++ lib/CodeGen/TargetLoweringBase.cpp @@ -38,6 +38,12 @@ #include using namespace llvm; + +static cl::opt JumpIsExpensiveOverride( + "jump-is-expensive", cl::init(false), + cl::desc("Do not create extra branches to split comparison logic."), + cl::Hidden); + /// InitLibcallNames - Set default libcall names. /// static void InitLibcallNames(const char **Names, const Triple &TT) { @@ -757,7 +763,7 @@ IntDivIsCheap = false; FsqrtIsCheap = false; Pow2SDivIsCheap = false; - JumpIsExpensive = false; + JumpIsExpensive = JumpIsExpensiveOverride; PredictableSelectIsExpensive = false; MaskAndBranchFoldingIsLegal = false; EnableExtLdPromotion = false; @@ -915,6 +921,13 @@ } } +void TargetLoweringBase::setJumpIsExpensive(bool isExpensive) { + // If the command-line option was specified, ignore this request. + if (!JumpIsExpensiveOverride.getNumOccurrences()) + JumpIsExpensive = isExpensive; +} + + TargetLoweringBase::LegalizeKind TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const { // If this is a simple type, use the ComputeRegisterProp mechanism. Index: test/CodeGen/X86/or-branch.ll =================================================================== --- test/CodeGen/X86/or-branch.ll +++ test/CodeGen/X86/or-branch.ll @@ -1,18 +1,31 @@ -; RUN: llc < %s -march=x86 | not grep set +; RUN: llc < %s -mtriple=i386-unknown-unknown -jump-is-expensive=0 | FileCheck %s --check-prefix=JUMPY +; RUN: llc < %s -mtriple=i386-unknown-unknown -jump-is-expensive=1 | FileCheck %s --check-prefix=NOJMP define void @foo(i32 %X, i32 %Y, i32 %Z) nounwind { +; JUMPY-LABEL: foo: +; JUMPY: cmpl $5, %edi +; JUMPY-NEXT: jl +; JUMPY: testl %esi, %esi +; JUMPY-NEXT: je +; +; NOJMP-LABEL: foo: +; NOJMP: cmpl $0, {{[0-9]+}}(%esp) +; NOJMP-NEXT: sete %al +; NOJMP-NEXT: cmpl $5, %esi +; NOJMP-NEXT: setl %cl +; NOJMP-NEXT: orb %al, %cl entry: - %tmp = tail call i32 (...) @bar( ) ; [#uses=0] - %tmp.upgrd.1 = icmp eq i32 %X, 0 ; [#uses=1] - %tmp3 = icmp slt i32 %Y, 5 ; [#uses=1] - %tmp4 = or i1 %tmp3, %tmp.upgrd.1 ; [#uses=1] + %tmp = tail call i32 (...) @bar( ) + %tmp1 = icmp eq i32 %X, 0 + %tmp3 = icmp slt i32 %Y, 5 + %tmp4 = or i1 %tmp3, %tmp1 br i1 %tmp4, label %cond_true, label %UnifiedReturnBlock -cond_true: ; preds = %entry - %tmp5 = tail call i32 (...) @bar( ) ; [#uses=0] +cond_true: + %tmp5 = tail call i32 (...) @bar( ) ret void -UnifiedReturnBlock: ; preds = %entry +UnifiedReturnBlock: ret void }