Hello, my target has libcall support for long long shifts. I already have the following lines in my Lowering constructor: setLibcallName(RTLIB::SHL_I64, "__llshl"); setLibcallName(RTLIB::SRL_I64, "__llshru"); setLibcallName(RTLIB::SRA_I64, "__llshr"); and setOperationAction(ISD::SHL, MVT::i64, Expand); setOperationAction(ISD::SRA, MVT::i64, Expand); setOperationAction(ISD::SRL, MVT::i64, Expand); But when I try to compile a sample program, I get the error: NODE: 0x273c850: i64 = shl 0x273b800, 0x273be00 llc: LegalizeDAG.cpp:1011: llvm::SDValue {anonymous}::SelectionDAGLegalize::LegalizeOp(llvm::SDValue): Assertion `0 && "Do not know how to legalize this operator!"' failed. ... Well, I thought that was the way to tell LLVM to expand to a libcall. What's the problem? How can I convince LLVM to expand to a libcall here? (ARM does intrinsics magics here. Is this the (only) way to do it?) Regards, Johannes
On Sat, Jan 7, 2012 at 10:18 AM, Johannes Birgmeier <e0902998 at student.tuwien.ac.at> wrote:> Hello, > > my target has libcall support for long long shifts. I already have the > following lines in my Lowering constructor: > > setLibcallName(RTLIB::SHL_I64, "__llshl"); > setLibcallName(RTLIB::SRL_I64, "__llshru"); > setLibcallName(RTLIB::SRA_I64, "__llshr"); > > and > > setOperationAction(ISD::SHL, MVT::i64, Expand); > setOperationAction(ISD::SRA, MVT::i64, Expand); > setOperationAction(ISD::SRL, MVT::i64, Expand); > > But when I try to compile a sample program, I get the error: > NODE: 0x273c850: i64 = shl 0x273b800, 0x273be00 > > llc: LegalizeDAG.cpp:1011: llvm::SDValue > {anonymous}::SelectionDAGLegalize::LegalizeOp(llvm::SDValue): Assertion > `0 && "Do not know how to legalize this operator!"' failed. > > ... Well, I thought that was the way to tell LLVM to expand to a > libcall. What's the problem? How can I convince LLVM to expand to a > libcall here? > (ARM does intrinsics magics here. Is this the (only) way to do it?)Is i64 a legal type on your target? If so, you might need to hack the code generator a bit; no in-tree target has a legal integer type that doesn't support shifts. If not, I have no idea how you're getting that error. -Eli
> Is i64 a legal type on your target? If so, you might need to hack the > code generator a bit; no in-tree target has a legal integer type that > doesn't support shifts. If not, I have no idea how you're getting > that error.Yes, well, i64 is a legal type, that's how it is. However, i64s are always stored in two 32-bit registers and in some cases need complicated instruction patterns for easy things (such as add, sub and so on) that basically simulate the i64 behaviour with a sequence of i32 instructions. Simulating an i64 shift with two variables (no immediates) with i32 instructions is so complicated that the target (the TI C64x+ family) has libcalls for them. Instructions for i32 shift exist, of course. Thanks for your help. I'll maybe start tearing up the code generator then. (I've already tried just copying the MakeLibCall function from the right class into our *Lowering.cpp and calling it using custom lowering, but some pass doesn't like that; I suspect it's our scheduler.) Regards, Johannes