Notes for future cleanups: > + /* If the targer has no lshift in word_mode, the operation will most > + probably not be cheap. ??? Does GCC even work for such targets? */
Yes, it does. We're perfectly happy to let this expand to a libcall. Indeed, many teeny tiny targets don't have a full barrel shifter and only implement x << 1. See sh1, avr, etc. > + int cost = set_src_cost (gen_rtx_ASHIFT (word_mode, const1_rtx, reg), ... > +if CST constains at least 3 bits, and "x << 1" is cheap. The bit tests are Code is correct, comment is incorrect: 1 << x. > +* The compounded constant could be shifted rather than the one. The > + test would be either on the sign bit or on the least significant bit, > + depending on the direction of the shift. On some machines, the test > + for the branch would be free if the bit to test is already set by the > + shift operation. I'm reasonably certain that this would be an improvement for most targets. Ignoring the possibility of using the sign bit (which I hadn't considered), most targets don't have a (1 << x) insn, requiring an insn to load the constant. Whereas many targets have a test (or even test-and-branch) insn that allows an immediate 1. Even on i386, where the test insn can hold the compounded constant, we get smaller code for 0: b8 78 56 34 12 mov $0x12345678,%eax 5: d3 e8 shr %cl,%eax 7: a8 01 test $0x1,%al 9: 90 nop vs 10: b8 01 00 00 00 mov $0x1,%eax 15: d3 e0 shl %cl,%eax 17: a9 78 56 34 12 test $0x12345678,%eax 1c: 90 nop r~