Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -4667,6 +4667,10 @@ if (!match(BB.getTerminator(), m_Br(m_OneUse(m_BinOp(LogicOp)), TBB, FBB))) continue; + auto *Br1 = cast(BB.getTerminator()); + if (Br1->getMetadata(LLVMContext::MD_unpredictable)) + continue; + unsigned Opc; Value *Cond1, *Cond2; if (match(LogicOp, m_And(m_OneUse(m_Value(Cond1)), @@ -4693,7 +4697,6 @@ // Update original basic block by using the first condition directly by the // branch instruction and removing the no longer needed and/or instruction. - auto *Br1 = cast(BB.getTerminator()); Br1->setCondition(Cond1); LogicOp->eraseFromParent(); Index: test/CodeGen/AArch64/fast-isel-branch-cond-split.ll =================================================================== --- test/CodeGen/AArch64/fast-isel-branch-cond-split.ll +++ test/CodeGen/AArch64/fast-isel-branch-cond-split.ll @@ -36,7 +36,59 @@ ret i64 %2 } +; If the branch is unpredictable, don't add another branch. + +; CHECK-LABEL: test_or_unpredictable +; CHECK: cmp w0, #0 +; CHECK-NEXT: cset w8, eq +; CHECK-NEXT: cmp w1, #0 +; CHECK-NEXT: cset w9, eq +; CHECK-NEXT: orr w8, w8, w9 +; CHECK-NEXT: and w8, w8, #0x1 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: b.ne +define i64 @test_or_unpredictable(i32 %a, i32 %b) { +bb1: + %0 = icmp eq i32 %a, 0 + %1 = icmp eq i32 %b, 0 + %or.cond = or i1 %0, %1 + br i1 %or.cond, label %bb3, label %bb4, !unpredictable !2 + +bb3: + ret i64 0 + +bb4: + %2 = call i64 @bar() + ret i64 %2 +} + +; CHECK-LABEL: test_and_unpredictable +; CHECK: cmp w0, #0 +; CHECK-NEXT: cset w8, ne +; CHECK-NEXT: cmp w1, #0 +; CHECK-NEXT: cset w9, ne +; CHECK-NEXT: and w8, w8, w9 +; CHECK-NEXT: and w8, w8, #0x1 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: b.eq +define i64 @test_and_unpredictable(i32 %a, i32 %b) { +bb1: + %0 = icmp ne i32 %a, 0 + %1 = icmp ne i32 %b, 0 + %or.cond = and i1 %0, %1 + br i1 %or.cond, label %bb4, label %bb3, !unpredictable !2 + +bb3: + ret i64 0 + +bb4: + %2 = call i64 @bar() + ret i64 %2 +} + declare i64 @bar() !0 = !{!"branch_weights", i32 5128, i32 32} !1 = !{!"branch_weights", i32 1024, i32 4136} +!2 = !{} +