carl-llvm-dev@petosoft.com via llvm-dev
2019-Feb-19 20:38 UTC
[llvm-dev] AVR is little endian, but requires function arguments to be in a "big endian" order, might need an additional data layout variable unless someone can suggest a better fix?
I think this is broken in at least one place when legalising the DAG. This llvm ir: %3 = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %2, i16 11) Fails to lower correctly on AVR but the problem is, unfortunately, not just coming from the AVR Target code and I am not sure it can be cleanly fixed just there. (But I would be very happy to be proved wrong as I'm very new to this.) The above code is taken by the legalizer and turned into a call to __mulsi3, but turns the 16 bit parameters into 32 bit parameters by adding 16 bits of 0 to the top 16 bits of each. Unfortunately, to do this, it changes the code to be a call to __mulsi3 with four 16 bit parameters instead of two 32 bit parameters. It orders these parameters based on the endianness of the platform, read from the data layout. Unfortunately that doesn't match the AVR ABI, which expects 32 bit parameters to be passed in four consecutive registers, yet generally takes parameters in a sort of "big endian" order. Details can be found on my bug report to the AVR team: https://github.com/avr-rust/rust/issues/129 In order to get around this, the only way to deal with this I can think of is to add an extra field to the data layout for ABIEndianness or something like that, because otherwise the information that these were 32 bit parameters, not two 16 bit parameters has been lost after legalization. Any help much appreciated! Thanks, Carl p.s. I came up with a sample/demo PR for the sort of thing I'm talking about. Definitely not a finished product, just for discussion: https://github.com/avr-rust/llvm/pull/8. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190219/0e644992/attachment.html>
Eli Friedman via llvm-dev
2019-Feb-19 20:44 UTC
[llvm-dev] AVR is little endian, but requires function arguments to be in a "big endian" order, might need an additional data layout variable unless someone can suggest a better fix?
Adding a method to TargetLowering makes sense, sure. (I don’t think we need to modify the IR because the difference doesn’t affect IR optimizations.) -Eli From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of carl-llvm-dev at petosoft.com via llvm-dev Sent: Tuesday, February 19, 2019 12:38 PM To: LLVM Developers Mailing List <llvm-dev at lists.llvm.org> Subject: [EXT] [llvm-dev] AVR is little endian, but requires function arguments to be in a "big endian" order, might need an additional data layout variable unless someone can suggest a better fix? I think this is broken in at least one place when legalising the DAG. This llvm ir: %3 = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %2, i16 11) Fails to lower correctly on AVR but the problem is, unfortunately, not just coming from the AVR Target code and I am not sure it can be cleanly fixed just there. (But I would be very happy to be proved wrong as I'm very new to this.) The above code is taken by the legalizer and turned into a call to __mulsi3, but turns the 16 bit parameters into 32 bit parameters by adding 16 bits of 0 to the top 16 bits of each. Unfortunately, to do this, it changes the code to be a call to __mulsi3 with four 16 bit parameters instead of two 32 bit parameters. It orders these parameters based on the endianness of the platform, read from the data layout. Unfortunately that doesn't match the AVR ABI, which expects 32 bit parameters to be passed in four consecutive registers, yet generally takes parameters in a sort of "big endian" order. Details can be found on my bug report to the AVR team: https://github.com/avr-rust/rust/issues/129 In order to get around this, the only way to deal with this I can think of is to add an extra field to the data layout for ABIEndianness or something like that, because otherwise the information that these were 32 bit parameters, not two 16 bit parameters has been lost after legalization. Any help much appreciated! Thanks, Carl p.s. I came up with a sample/demo PR for the sort of thing I'm talking about. Definitely not a finished product, just for discussion: https://github.com/avr-rust/llvm/pull/8. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190219/15262240/attachment.html>
carl-llvm-dev@petosoft.com via llvm-dev
2019-Feb-20 10:16 UTC
[llvm-dev] AVR is little endian, but requires function arguments to be in a "big endian" order, might need an additional data layout variable unless someone can suggest a better fix?
Cool, looking into that as an option, sounds ideal. Thanks for the steer. :) I'll get back to you guys with results and a patch (probably via the maintainer, Dylan). Carl -----Original Message----- From: "Eli Friedman" <efriedma at quicinc.com> Sent: Tuesday, February 19, 2019 3:44pm To: "carl-llvm-dev at petosoft.com" <carl-llvm-dev at petosoft.com>, "LLVM Development List" <llvm-dev at lists.llvm.org> Subject: RE: [llvm-dev] AVR is little endian, but requires function arguments to be in a "big endian" order, might need an additional data layout variable unless someone can suggest a better fix? Adding a method to TargetLowering makes sense, sure. (I don’t think we need to modify the IR because the difference doesn’t affect IR optimizations.) -Eli From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of carl-llvm-dev at petosoft.com via llvm-dev Sent: Tuesday, February 19, 2019 12:38 PM To: LLVM Developers Mailing List <llvm-dev at lists.llvm.org> Subject: [EXT] [llvm-dev] AVR is little endian, but requires function arguments to be in a "big endian" order, might need an additional data layout variable unless someone can suggest a better fix? I think this is broken in at least one place when legalising the DAG. This llvm ir: %3 = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %2, i16 11) Fails to lower correctly on AVR but the problem is, unfortunately, not just coming from the AVR Target code and I am not sure it can be cleanly fixed just there. (But I would be very happy to be proved wrong as I'm very new to this.) The above code is taken by the legalizer and turned into a call to __mulsi3, but turns the 16 bit parameters into 32 bit parameters by adding 16 bits of 0 to the top 16 bits of each. Unfortunately, to do this, it changes the code to be a call to __mulsi3 with four 16 bit parameters instead of two 32 bit parameters. It orders these parameters based on the endianness of the platform, read from the data layout. Unfortunately that doesn't match the AVR ABI, which expects 32 bit parameters to be passed in four consecutive registers, yet generally takes parameters in a sort of "big endian" order. Details can be found on my bug report to the AVR team: [ https://github.com/avr-rust/rust/issues/129 ]( https://github.com/avr-rust/rust/issues/129 ) In order to get around this, the only way to deal with this I can think of is to add an extra field to the data layout for ABIEndianness or something like that, because otherwise the information that these were 32 bit parameters, not two 16 bit parameters has been lost after legalization. Any help much appreciated! Thanks, Carl p.s. I came up with a sample/demo PR for the sort of thing I'm talking about. Definitely not a finished product, just for discussion: [ https://github.com/avr-rust/llvm/pull/8 ]( https://github.com/avr-rust/llvm/pull/8 ). -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190220/322fab02/attachment-0001.html>
Reasonably Related Threads
- Legalising seems to lose critical information needed for lowering return values properly?
- Status of the AVR backend
- How to add new AVR targets?
- Built in progmem variables in AVR
- Lowering a reasonably complex struct seems to create over complex and invalid assembly fixups on some targets