In the case of a conditional branch without a preceding cmp or similar we
used to emit a "and; cmp; b.eq/b.ne" sequence, use tbz/tbnz instead.
rdar://18783875
Paths
| Differential D15122
AArch64FastISel: Use cbz/cbnz to branch on i1 ClosedPublic Authored by MatzeB on Dec 1 2015, 10:37 AM.
Details Summary In the case of a conditional branch without a preceding cmp or similar we rdar://18783875
Diff Detail
Event TimelineMatzeB updated this object. t.p.northover edited edge metadata. Comment ActionsI don't think this is quite right. The i1 content of a register is only the low bit, isn't it? This is most easily seen outside Darwin (we're the only ones that extend incoming paramters in the caller), but I think this gets miscompiled even for us: define i32 @foo(i32 %in) { entry: %val = trunc i32 %in to i1 br label %do_test do_test: %tst = phi i1 [%val, %entry] br i1 %tst, label %true, label %false true: ret i32 0 false: ret i32 1 } So I think we really do need the TBZ for correctness. This revision now requires changes to proceed.Dec 1 2015, 10:54 AM Comment Actions
I tried your example and even the non-fast-isel produce by "llc -march arm64 -O0" seems to use plain cbz, is this a bug? I was looking at TargetLowering::getBooleanContents() comments: "For targets without i1 registers, this gives the nature of the high-bits of boolean values held in types wider than i1." for aarch64 this is "ZeroOrOneBooleanContent". MatzeB updated this object. MatzeB edited edge metadata. Comment ActionsAfter discussing this with Tim, I realized that the "getBooleanContents() properties" are only guaranteed only for the usual boolean inputs of branches/selects/... and only after selection DAG legalization. So we shouldn't rely on that in the FastISel variants and I changed the code to use tbz/tbnz which should be as efficient anyway. This new version also removes a BrCond(Trunc) special case which was creating more complicated code than the default case now. (I also see no regressions on the test-suite with this patch). t.p.northover edited edge metadata. Comment ActionsThis looks fine to me. Thanks for updating the patch! Tim. This revision is now accepted and ready to land.Dec 2 2015, 6:21 PM Closed by commit rL254621: AArch64FastISel: Use cbz/cbnz to branch on i1 (authored by matze). · Explain WhyDec 3 2015, 9:23 AM This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 41767 llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
llvm/trunk/test/CodeGen/AArch64/arm64-fast-isel-br.ll
llvm/trunk/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll
llvm/trunk/test/CodeGen/AArch64/fast-isel-branch-cond-split.ll
|