[LLVMdev] Possible bug in ExpandShiftWithUnknownAmountBit

Duncan Sands baldrick at free.fr
Tue Dec 1 02:07:21 PST 2009


Hi Javier,

> The problem is the implementation of the expansion. Perhaps an example 
> can help illustrate better. Take the case of a 64-bit integer shifted 
> left by say 6 bits and is decomposed using 32-bit registers. Because 6 
> is less than the 32 (the register size) the resulting low part should be 
> equal to the source low part shifted left by 6 bits. The current 
> implementation places a zero instead. All other values have similar 
> errors. Below is the current and proposed expansion in pseudo C++ for 
> all shift functions. Please let me know if I something is unclear.

I'm not sure what you are saying, here is the code for shift-left.  In
the case of your example, Amt = 6, VTBits = 64 and NVTBits = 32.  I've
added comments at the end of various lines, like this: <== Comment.

   if (N->getOpcode() == ISD::SHL) { <== This branch is taken
     if (Amt > VTBits) { <== False
... not executed ...
     } else if (Amt > NVTBits) { <== False
... not executed ...
     } else if (Amt == NVTBits) { <== False
... not executed ...
     } else if (Amt == 1 &&
                TLI.isOperationLegalOrCustom(ISD::ADDC, 
TLI.getTypeToExpandTo(*DAG.getContext(), NVT))) { <== False
... not executed ...
     } else { <== This branch is taken
       Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Amt, ShTy)); <== 
Source low part is shifted left by 6 bits
       Hi = DAG.getNode(ISD::OR, dl, NVT,
                        DAG.getNode(ISD::SHL, dl, NVT, InH,
                                    DAG.getConstant(Amt, ShTy)),
                        DAG.getNode(ISD::SRL, dl, NVT, InL,
                                    DAG.getConstant(NVTBits-Amt, ShTy))); <== 
Source high part is shifted left by 6 bits, and the top 6 bits of the low part 
is or'd in
     }
     return;
   }

In short, the current code seems to be correct.

Ciao,

Duncan.



More information about the llvm-dev mailing list