Index: lib/Target/Lanai/LanaiSetflagAluCombiner.cpp =================================================================== --- lib/Target/Lanai/LanaiSetflagAluCombiner.cpp +++ lib/Target/Lanai/LanaiSetflagAluCombiner.cpp @@ -228,20 +228,22 @@ MbbIterator SCCUserIter = Instruction; while (SCCUserIter != End) { ++SCCUserIter; - // Early exit when encountering flag setting instruction. - if (isFlagSettingInstruction(SCCUserIter->getOpcode())) - break; + // Early exit when encountering flag setting or return instruction. + if (isFlagSettingInstruction(SCCUserIter->getOpcode()) || + SCCUserIter->isReturn()) + // Only return true if flags are set post the flag setting instruction + // tested or a return is executed. + return true; int CCIndex = getCCOperandPosition(SCCUserIter->getOpcode()); if (CCIndex != -1) { LPCC::CondCode CC = static_cast( SCCUserIter->getOperand(CCIndex).getImm()); + // Return false if the flag is used outside of a EQ, NE, PL and MI. if (CC != LPCC::ICC_EQ && CC != LPCC::ICC_NE && CC != LPCC::ICC_PL && CC != LPCC::ICC_MI) return false; } } - - return true; } return false; Index: test/CodeGen/Lanai/combined_alu_setcc.ll =================================================================== --- test/CodeGen/Lanai/combined_alu_setcc.ll +++ test/CodeGen/Lanai/combined_alu_setcc.ll @@ -121,6 +121,50 @@ ret i32 %retval.0 } ; CHECK-LABEL: test4 -; CHECK: and.f -; CHECK: and.f -; CHECK: and.f +; TODO: Re-enable test. This test is disabled post making the combiner more +; conservative. +; DISABLED_CHECK: and.f + +; Test to avoid incorrect fusing that spans across basic blocks +@a = global i32 -1, align 4 +@b = global i32 0, align 4 + +; Function Attrs: nounwind +define void @testBB() { +entry: + %0 = load i32, i32* @a, align 4, !tbaa !1 + %1 = load i32, i32* @b, align 4, !tbaa !1 + %sub.i = sub i32 %1, %0 + %tobool = icmp sgt i32 %sub.i, -1 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + %call1 = tail call i32 bitcast (i32 (...)* @g to i32 ()*)() + br label %while.body + +while.body: ; preds = %if.then, %while.body + br label %while.body + +if.end: ; preds = %entry + %cmp.i = icmp slt i32 %sub.i, 1 + br i1 %cmp.i, label %if.then4, label %if.end7 + +if.then4: ; preds = %if.end + %call5 = tail call i32 bitcast (i32 (...)* @g to i32 ()*)() + br label %while.body6 + +while.body6: ; preds = %if.then4, %while.body6 + br label %while.body6 + +if.end7: ; preds = %if.end + ret void +} + +declare i32 @g(...) +; CHECK-LABEL: testBB +; CHECK: sub.f {{.*}}, %r0 + +!1 = !{!2, !2, i64 0} +!2 = !{!"int", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"}