Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2430,9 +2430,11 @@ // Use volatile double here to avoid excess precision issues on some hosts, // e.g. that use 80-bit X87 registers. volatile double LDensity = - LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble(); + LEnd == First ? 0.0 : LSize.roundToDouble() / + (LEnd - First + 1ULL).roundToDouble(); volatile double RDensity = - RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble(); + Last == RBegin ? 0.0 : RSize.roundToDouble() / + (Last - RBegin + 1ULL).roundToDouble(); volatile double Metric = Range.logBase2() * (LDensity + RDensity); // Should always split in some non-trivial place DEBUG(dbgs() <<"=>Step\n" Index: test/CodeGen/X86/switch-jump-table.ll =================================================================== --- test/CodeGen/X86/switch-jump-table.ll +++ test/CodeGen/X86/switch-jump-table.ll @@ -50,3 +50,59 @@ ; CHECK-NEXT: .long .LBB0_5 ; CHECK-NOT: .long } + +; Ensure that optimizing for jump tables doesn't needlessly deteriorate the +; created binary tree search. See PR22262. +define void @test(i32 %x, i32* %y) { +; CHECK-LABEL: test: + +entry: + switch i32 %x, label %sw.default [ + i32 10, label %sw.bb + i32 20, label %sw.bb1 + i32 30, label %sw.bb2 + i32 40, label %sw.bb3 + i32 50, label %sw.bb4 + i32 60, label %sw.bb5 + ] +sw.bb: + store i32 1, i32* %y + br label %sw.epilog +sw.bb1: + store i32 2, i32* %y + br label %sw.epilog +sw.bb2: + store i32 3, i32* %y + br label %sw.epilog +sw.bb3: + store i32 4, i32* %y + br label %sw.epilog +sw.bb4: + store i32 5, i32* %y + br label %sw.epilog +sw.bb5: + store i32 6, i32* %y + br label %sw.epilog +sw.default: + store i32 7, i32* %y + br label %sw.epilog +sw.epilog: + ret void +; The correct binary switch here would start with a comparison against 39. +; CHECK: cmpl $29 +; CHECK: jg +; CHECK: cmpl $10 +; CHECK: jne +; CHECK: cmpl $49 +; CHECK: jg +; CHECK: cmpl $30 +; CHECK: jne +; CHECK: cmpl $20 +; CHECK: jne +; CHECK: cmpl $50 +; CHECK: jne +; CHECK: cmpl $40 +; CHECK: jne +; CHECK: cmpl $60 +; CHECK: jne +}