Fabian Scheler
2012-Jul-12 11:22 UTC
[LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
Hi Micah,> We have a very similar setup with the AMDIL backend(some operations support 64bit some don't). > > What we do is we enable MVT::i64, set legal to all operands that are legal and then set everything else to expand.thanks for your hint. Unfortunately, I didn't find any time to work on my problem in the meantime as I was busy preparing lectures. However, the summer term is almost over now and I can get back to this. I already tried what you suggested, however I still end up getting the following error message: LLVM ERROR: Cannot select: 0x2299fb0: i64 = Constant<1> [ORD=1] [ID=1] Just setting the Action to Expand here via setOperationAction(ISD::Constant,MVT::i64,Expand); does not solve the problem. I took a look into your AMDIL-patch and found out that your target supports this operation. I have the feeling that this has to be lowered manually or has to be handled by ISelDAGtoDAG or similar. Well, I guess I have to dig a little bit deeper. If you have any other suggestion - I definitely am interested ;-) Ciao, Fabian
Tom Stellard
2012-Jul-12 13:08 UTC
[LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
On Thu, Jul 12, 2012 at 01:22:39PM +0200, Fabian Scheler wrote:> Hi Micah, > > > We have a very similar setup with the AMDIL backend(some operations support 64bit some don't). > > > > What we do is we enable MVT::i64, set legal to all operands that are legal and then set everything else to expand. > > thanks for your hint. Unfortunately, I didn't find any time to work on > my problem in the meantime as I was busy preparing lectures. However, > the summer term is almost over now and I can get back to this. > > I already tried what you suggested, however I still end up getting the > following error message: > > LLVM ERROR: Cannot select: 0x2299fb0: i64 = Constant<1> [ORD=1] [ID=1] > > Just setting the Action to Expand here via > > setOperationAction(ISD::Constant,MVT::i64,Expand); > > does not solve the problem. I took a look into your AMDIL-patch and > found out that your target supports this operation. I have the feeling > that this has to be lowered manually or has to be handled by > ISelDAGtoDAG or similar. > > Well, I guess I have to dig a little bit deeper. If you have any other > suggestion - I definitely am interested ;-) >I took a look at lib/CodeGen/SelectionDAG/LegalizeDAG.cpp and it doesn't look like there is an Expand operation implemented for ISD::Constant. I think you'll either need implement Expand for ISD::Constant or Custom lower it in your backend. Also, why is your frontend generating 64-bit constants? -Tom> Ciao, Fabian > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Fabian Scheler
2012-Jul-18 11:45 UTC
[LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
Hello Tom,> I took a look at lib/CodeGen/SelectionDAG/LegalizeDAG.cpp and it > doesn't look like there is an Expand operation implemented for > ISD::Constant. I think you'll either need implement Expand for > ISD::Constant or Custom lower it in your backend.thank you for that information. This exactly is what I feared. Well I did some more mostly unguided hacking and these are the opportunities I found/was pointed to: 1. Implement custom lowering in the backend (cf. eg. SDNode *PPCDAGToDAGISel::Select(SDNode *N)) It is not a big issue to split the constant in the 32 higher and lower bits and to load these fragments separately. However, I don't know how to ensure that these fragments are put into the proper subregisters of the register pair forming the 64bit register. For the PPC-backend this is no problem as it has true 64bit register, this however is not the case for the TriCore. So I need to get the vritual register (pair) that will be used to store the 64bit value to access its subregisters. 2. Use a pattern consisting of INSERT_SUBREG-nodes A colleague of mine (who originally implemented the TriCore-backend) suggested to use a pattern that replaces 64bit-constants by tow INSERT_SUBREG-nodes. I ended up having the following pattern: def : Pat<(i64 imm:$imm), (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (i32 (LO32 imm:$imm)), sub_even), (i32 (HI32 imm:$imm)), sub_odd)>; OK, this leaves a DAG where all i64-Constant-nodes are replaced by to nested INSERT_SUBREG-nodes, but how do I get rid of that INSERT_SUBREG-stuff. Do I have to lower it separately? Should there be some magic that eliminates those nodes for me? Maybe, I just have to make clear that (LO32 imm:$imm) yields a 32bit-Constant (How can I do this?), as there is another pattern to load a 32bit-Constant into a register. Is there some documentation how all this INSERT_SUBREG-stuff should be used and how it should work? I didn't find anything helpful here. Is INSERT_SUBREG suitable to solve that kind of problem? In an older post, INSERT_SUBREG was envisaged to load an i16-Value into a pair of 8bit-registers in the PIC-backend, however the outcome of this was not mentioned. I also didn't not find any INSERT_SUBREG-stuff in the PIC-backend in LLVM 2.7. Maybe, someone else knows something about it, the post is here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2008-October/017443.html I really whish I could force TypeLegalization to expand i64 although adding a 64bit-Register class ...> Also, why is your frontend generating 64-bit constants?Well, using clang to translate to following piece of code: unsigned long long do_something(unsigned long long); unsigned long long myfunc(unsigned long long param) { unsigned long long b = 4500000; unsigned long long c = b + param; return c + do_something(5); } yields an LLVM-assembly file containing 64bit constants as follows: define i64 @myfunc(i64 %param) nounwind uwtable { %1 = alloca i64, align 8 %b = alloca i64, align 8 %c = alloca i64, align 8 store i64 %param, i64* %1, align 8 store i64 4500000, i64* %b, align 8 %2 = load i64* %b, align 8 %3 = load i64* %1, align 8 %4 = add i64 %2, %3 store i64 %4, i64* %c, align 8 %5 = load i64* %c, align 8 %6 = call i64 @do_something(i64 5) %7 = add i64 %5, %6 ret i64 %7 } declare i64 @do_something(i64) Ciao, Fabian
Apparently Analagous Threads
- [LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
- [LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
- [LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
- [LLVMdev] Instructions working on 64bit registers without true support for 64bit operations
- [LLVMdev] atomic operations for ARM