This is an update of:
http://reviews.llvm.org/rL262424
That was reverted because it caused failures in an end-to-end clang AArch64 test ( clang/test/CodeGen/aarch64-neon-misc.c ).
That failure no longer happens after:
http://reviews.llvm.org/rL262623
Ie, the AArch64 backend recognizes the pattern produced by this patch and generates the expected code.
There is an end-to-end improvement for AArch64 from this patch that is not currently tested anywhere AFAIK. That is noted in PR26819:
https://llvm.org/bugs/show_bug.cgi?id=26819
This source:
// Are elements of 'a' <= -1? Ie, is 'a' negative? int32x2_t test_vcle_s32(int32x2_t a) { return vcle_s32(a, vceq_s32(a, a) ); }
Becomes:
test_vcle_s32: sshr v0.2s, v0.2s, #31 ret
Instead of the current:
test_vcle_s32: movi d1, #0xffffffffffffffff cmge v0.2s, v1.2s, v0.2s ret
Given the current controversy about end-to-end testing, I have not included a test for that in this patch. But it seems to me that we should have that kind of test *somewhere* to make sure that IR optimizations are correctly handled by a backend. In other words, if that current end-to-end AArch clang test didn't exist, I wouldn't have known that this patch pessimized AArch64. It's entirely possible that some other backend will still be pessimized by this change because it has no equivalent end-to-end test. The difference is sufficiently small that it is unlikely to show up as a perf regression anywhere, but it undoubtedly would be a regression.
I usually see canonicalization as something that is target independent, and then after optimization the lowering can adjust toward something that the target will "like" (ultimately the SDAG legalizer is doing this). Any comment?