I've had a bug/pessimization which I've tracked down for 1 bit bitmasks: if (((xx) & (1ULL << (40)))) return 1; if (!((yy) & (1ULL << (40)))) ... The second time Constant Hoisting sees the value (1<<40) it wraps it up with a bitcast. That value then gets hoisted. However, the first (1<<40) is not bitcast and gets recognized as a BT. The second doesn't get recognised because of the hoisting. The result is some register allocation and unnecessary constant loading instructions. There are maybe three 'solutions' to this problem, maybe more. Starting with the second, in the middle of things, you could try pattern matching in EmitTest() or LowerToBT(). I've tried this and it doesn't work since it needs to reach outside of a Selection DAG. Doesn't work. Can't work. Thirdly, it's been suggested to use a peephole pass and to look at AArch64LoadStoreOptimizer.cpp. This also doesn't work for pretty much the same reason. Moreover, this is after register allocation so even for the limited situations where it can work, it leaves allocated but unutilized registers. Doesn't work. In fact, I'd suggest the Arm backend adopt my approach. So firstly, I think the best way to solve this problem is to avoid this problem in the first place. Just don't hoist these values. For the X86 backend, X86TTI::getIntImmCost() in X86TargetTransformInfo.cpp is an overridden function. Just mark these 1 bit masks there as TCC_Free: // Don't hoist 1 bit masks. They'll probably be used for BT, BTS, BTC. if (Imm.isPowerOf2()) // this could be limited to bits 32-63 return TCC_Free; This works. Its only downside is when these values are being used twice AND then not being combined into another instruction. I'd also recommend looking at not hoisting other values. However I haven't really looked this over very thoroughly. // Don't hoist imm8 if (Imm.isSignedIntN(8)) return TCC_Free; -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150202/56d432d0/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: newtst.c Type: text/x-csrc Size: 1534 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150202/56d432d0/attachment.c>
I hadn't seen the godbolt compiler comparison site before. So I plugged newtst.c into it and my problem did not show up on any of the clang versions. I do not understand this but I will pull a fresh tree from SVN, reapply the patch and recompile from scratch. However, there was another bug which showed up between 3.3 and 3.4.1. I'd noticed this before and I was tracking it separately but I'd made no headway in solving it. With x86 3.4.1 (-O3 -march=native -x c), for some reason the last bit test expression isn't matching. (((xx) & (1ULL << (56)))) It generates movabsq $72057594037927936, %rcx # imm = 0x100000000000000 andq %rcx, %rdi However on 3.3, it (correctly) generates btq $56, %rdi jb .LBB0_13 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150202/c10ed333/attachment.html>
Yes, it does seem to be a regression (and not pilot error) although I can't imagine how. I pulled a new tree and recompiled. Untouched and unpatched the bugs are there. newtst.c newtst.ll and newtst.s are attached. LLVM (http://llvm.org/): LLVM version 3.7.0svn DEBUG build with assertions. Built Feb 2 2015 (22:14:40). Default target: x86_64-apple-darwin14.1.0 Host CPU: penryn /Users/Chris/Desktop/llvm-svn/build/Debug+Asserts/bin/clang -S -O2 -emit-llvm -arch x86_64 -march=core2 -asm-show-inst -asm-verbose newtst.c /Users/Chris/Desktop/llvm-svn/build/Debug+Asserts/bin/llc -O3 -print-before-all -print-after-all -debug-pass=Details newtst.ll -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150203/1697e1a6/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: newtst.s Type: application/octet-stream Size: 1796 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150203/1697e1a6/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: newtst.ll Type: application/octet-stream Size: 3230 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150203/1697e1a6/attachment-0001.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: newtst.c Type: text/x-csrc Size: 1534 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150203/1697e1a6/attachment.c>