<div dir="ltr">I'm tracking down an X86 code generation malfeasance regarding BT (bit test) and I have some questions.<div><br></div><div>This IR <b>matches</b> and then <i>X86TargetLowering::LowerToBT </i><b>is called:</b></div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>%and = and i64 %shl, %val     <i> ; (val & (1 << index)) != 0     ; </i>bit test with a <b>register</b> index</div></blockquote><div><br></div><div>This IR <b>does not match</b> and so <i>X86TargetLowering::LowerToBT </i><b>is not called<i>:</i></b></div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">%and = lshr i64 %val, 25         <i> ; (val & (1 </i><i><< 25)) != 0          ; </i>bit test with an <b>immediate</b> index<br></blockquote></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>%conv = and i64 %and, 1</div></div></blockquote><div><br></div><div>Let's back that up a bit. Clang emits this IR. These expressions start out life in C as <i>and with a left shifted masking bit</i>, and are then converted into IR as <i>right shifted values anded with a masking bit</i>.</div><div><br></div><div>This IR then remains untouched until <i>Expand ISel Pseudo-instructions</i> in llc (-O3). At that point, <i>LowerToBT</i> is called on the REGISTER version and substitutes in a BT reg,reg instruction:</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>btq<span class="" style="white-space:pre">     </span>%rsi, %rdi                          ## <MCInst #312 BT64rr</div></div></blockquote><br></div><div>The IMMEDIATE version doesn't match the pattern and so <i>LowerToBT</i> is not called.</div><div><br></div><div><b>Question</b>: This is during <i>pseudo instruction expansion</i>. How could <i>LowerToBT'</i>s caller have enough context to match the immediate IR version? In fact, lli isn't calling <i>LowerToBT</i> so it isn't matching. But isn't this really a <i>peephole optimization</i> issue?</div><div><br></div><div>LLVM has a generic peephole optimizer, <i>CodeGen/PeepholeOptimizer.cpp </i>which has exactly one subclass in <i>NVPTXTargetMachine.cpp.</i></div><div><br></div><div>But isn't it better to deal with X86 <i>LowerToBT</i> in a <i>PeepholeOptimizer</i> subclass where you have a small window of instructions rather than during pseudo instruction expansion where you have really one instruction? <i>PeepholeOptimizer </i>doesn't seem to be getting much attention and certainly no attention at the subclass level.</div><div><br></div><div>Bluntly, expansion is about expansion. Peephole optimization is the opposite.</div><div><div><div><br></div></div></div><div><b>Question</b>: Regardless, why is <i>LowerToBT</i> not being called for the IMMEDIATE version? I suppose you could look at the preceding instruction in the DAG. That seems a bit hacky<i>.</i></div><div><i><br></i></div><div>Another approach using <i>LowerToBT</i> would be to match <i>lshr reg/imm</i> first and then if the <i>following</i> instruction was an <i>and reg,1 </i>replace both with a BT<i>. </i>It doesn't look like <i>LowerToBT</i> as is can do that right now since it is matching the <i>and</i> instruction.</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div>SDValue X86TargetLowering::LowerToBT(<b>SDValue <u>And</u></b>, ISD::CondCode CC, SDLoc dl, SelectionDAG &DAG) const { ... }</div></div></blockquote><br></div><div>But I think this is better done in a subclass of <i>CodeGen/PeepholeOptimizer.cpp.</i></div><div><i><br></i></div><div>thanks.</div><div><br></div></div>