<div dir="ltr">I've had a bug/pessimization which I've tracked down for 1 bit bitmasks:<div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>if (((xx) & (1ULL << (40))))</div></div><div><div>   return 1;</div></div><div><div>if (!((yy) & (1ULL << (40))))</div></div><div>   ...</div></blockquote><div><div><br></div><div>The second time Constant Hoisting sees the value (1<<40) it wraps it up with a bitcast.</div></div><div>That value then gets hoisted. However, the first (1<<40) is not bitcast and gets recognized</div><div>as a BT. The second doesn't get recognised because of the hoisting.</div><div>The result is some register allocation and unnecessary constant loading instructions.</div><div><br></div><div>There are maybe three 'solutions' to this problem, maybe more.</div><div><br></div><div>Starting with the second, in the middle of things, you could try pattern matching in</div><div>EmitTest() or LowerToBT(). I've tried this and it doesn't work since it needs to reach</div><div>outside of a Selection DAG. Doesn't work. Can't work.</div><div><br></div><div>Thirdly, it's been suggested to use a peephole pass and to look at</div><div>AArch64LoadStoreOptimizer.cpp.  This also doesn't work for pretty much the</div><div>same reason. Moreover, this is after register allocation so even for the limited</div><div>situations where it can work, it leaves allocated but unutilized registers.</div><div>Doesn't work. In fact, I'd suggest the Arm backend adopt my approach.</div><div><br></div><div>So firstly, I think the best way to solve this problem is to avoid this problem</div><div>in the first place. Just don't hoist these values.</div><div><br></div><div>For the X86 backend, X86TTI::getIntImmCost() in X86TargetTransformInfo.cpp</div><div>is an overridden function. Just mark these 1 bit masks there as TCC_Free:</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>  // Don't hoist 1 bit masks. They'll probably be used for BT, BTS, BTC.</div><div>  if (Imm.isPowerOf2())       // this could be limited to bits 32-63</div><div>    return TCC_Free;</div></div></blockquote><br></div><div>This works. Its only downside is when these values are being used twice</div><div>AND then not being combined into another instruction.</div><div><br></div><div>I'd also recommend looking at not hoisting other values. However I haven't really</div><div>looked this over very thoroughly.</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>  // Don't hoist imm8</div><div>  if (Imm.isSignedIntN(8))</div><div>    return TCC_Free;</div></div></blockquote><br></div><div><br></div></div>