Patrik Hägglund
2012-Jan-19 10:16 UTC
[LLVMdev] Problem with cross class joins in the RegisterCoalescer
Hi, Is it intended that in some cases it is necessary to use "-disable-cross-class-join" to be sure the resulting code is ok? I have several cases where cross class joins are carried out that makes the code turn out illegal, because the "new" register class is not allowed in all instructions where it is now used. For example, by joining %vreg4, %vreg7 and %vreg9 the following code %vreg7<def> = COPY %vreg4:lo16; aNl_0_7:%vreg7 aN32_0_7:%vreg4 %vreg9<def> = COPY %vreg7; rN:%vreg9 aNl_0_7:%vreg7 %vreg17<def> = load %vreg9<kill>; aN40_0_7:%vreg17 rN:%vreg9 is turned into %vreg17<def> = load %vreg4:lo16<kill>; aN40_0_7:%vreg17 aN32_0_7:%vreg4 The load instruction however, can only use registers from the rN class, but the coalescer has changed so it now uses the lo16 part of a aN32 register (which it cannot). Moves can be carried out from a aN32:lo16 part to an rN register, but aN32:lo16 and rN cannot be replaced with eachother in all instructions. The "-disable-cross-class-join" flag prevents this problem from happening but I'm afraid it will also prevent other (non-problematic) cross class joins from happening so I'm hesitant to use it. So, should this not happen, or is the flag needed, or is this just a sign that we have a really weird or buggy register model?
Anton Korobeynikov
2012-Jan-19 13:27 UTC
[LLVMdev] Problem with cross class joins in the RegisterCoalescer
Hi Patrik,> The "-disable-cross-class-join" flag prevents this problem from > happening but I'm afraid it will also prevent other (non-problematic) > cross class joins from happening so I'm hesitant to use it. > > So, should this not happen, or is the flag needed, or is this just a > sign that we have a really weird or buggy register model?Is this some recent problem? Or it's seen with LLVM 3.0 as well? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Patrik Hägglund H
2012-Jan-19 13:46 UTC
[LLVMdev] Problem with cross class joins in the RegisterCoalescer
Sorry, our backend is currently based on LLVM 3.0. (We are currently in the process of rebasing.) /Patrik Hägglund -----Original Message----- From: Anton Korobeynikov [mailto:anton at korobeynikov.info] Sent: den 19 januari 2012 14:28 To: Patrik Hägglund H Cc: llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] Problem with cross class joins in the RegisterCoalescer Hi Patrik,> The "-disable-cross-class-join" flag prevents this problem from > happening but I'm afraid it will also prevent other (non-problematic) > cross class joins from happening so I'm hesitant to use it. > > So, should this not happen, or is the flag needed, or is this just a > sign that we have a really weird or buggy register model?Is this some recent problem? Or it's seen with LLVM 3.0 as well? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Jakob Stoklund Olesen
2012-Jan-19 15:45 UTC
[LLVMdev] Problem with cross class joins in the RegisterCoalescer
On Jan 19, 2012, at 2:16 AM, Patrik Hägglund <patrik.h.hagglund at ericsson.com> wrote:> Is it intended that in some cases it is necessary to use > "-disable-cross-class-join" to be sure the resulting code is ok?No.> I have several cases where cross class joins are carried out that makes > the code turn out illegal, because the "new" register class is not > allowed in all instructions where it is now used. > > For example, by joining %vreg4, %vreg7 and %vreg9 the following code > > %vreg7<def> = COPY %vreg4:lo16; aNl_0_7:%vreg7 aN32_0_7:%vreg4 > %vreg9<def> = COPY %vreg7; rN:%vreg9 aNl_0_7:%vreg7 > %vreg17<def> = load %vreg9<kill>; aN40_0_7:%vreg17 rN:%vreg9 > > is turned into > > %vreg17<def> = load %vreg4:lo16<kill>; aN40_0_7:%vreg17 > aN32_0_7:%vreg4 > > The load instruction however, can only use registers from the rN class, > but the coalescer has changed so it now uses the lo16 part of a aN32 > register (which it cannot).When sub-registers are involved, the coalescer uses the getMatchingSuperRegClass hook to determine if the cross class join is possible, and what the resulting register class should be. In this case it would call getMatchingSuperRegClass(aN32_0_7, aNl_0_7, lo16) Check your implementation of that hook, and reread the comment describing what it does. It is quite tricky to get it right. Or you could just rebase. On trunk, TableGen writes this difficult function for you.> So, should this not happen, or is the flag needed, or is this just a > sign that we have a really weird or buggy register model?We can handle weird, but not buggy. :-)
Patrik Hägglund H
2012-Jan-20 09:19 UTC
[LLVMdev] Problem with cross class joins in the RegisterCoalescer
Thanks! Our bug is now fixed. Our getMatchingSuperRegClass is huge (more than 300 lines), messy, and incomplete.> Or you could just rebase. On trunk, TableGen writes this difficult function for you.That in itself would be a compelling reason to get the rebase to trunk done. I just curious how large the generated version will be. :-) /Patrik Hägglund -----Original Message----- From: Jakob Stoklund Olesen [mailto:stoklund at 2pi.dk] Sent: den 19 januari 2012 16:46 To: Patrik Hägglund H Cc: llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] Problem with cross class joins in the RegisterCoalescer On Jan 19, 2012, at 2:16 AM, Patrik Hägglund <patrik.h.hagglund at ericsson.com> wrote:> Is it intended that in some cases it is necessary to use > "-disable-cross-class-join" to be sure the resulting code is ok?No.> I have several cases where cross class joins are carried out that makes > the code turn out illegal, because the "new" register class is not > allowed in all instructions where it is now used. > > For example, by joining %vreg4, %vreg7 and %vreg9 the following code > > %vreg7<def> = COPY %vreg4:lo16; aNl_0_7:%vreg7 aN32_0_7:%vreg4 > %vreg9<def> = COPY %vreg7; rN:%vreg9 aNl_0_7:%vreg7 > %vreg17<def> = load %vreg9<kill>; aN40_0_7:%vreg17 rN:%vreg9 > > is turned into > > %vreg17<def> = load %vreg4:lo16<kill>; aN40_0_7:%vreg17 > aN32_0_7:%vreg4 > > The load instruction however, can only use registers from the rN class, > but the coalescer has changed so it now uses the lo16 part of a aN32 > register (which it cannot).When sub-registers are involved, the coalescer uses the getMatchingSuperRegClass hook to determine if the cross class join is possible, and what the resulting register class should be. In this case it would call getMatchingSuperRegClass(aN32_0_7, aNl_0_7, lo16) Check your implementation of that hook, and reread the comment describing what it does. It is quite tricky to get it right. Or you could just rebase. On trunk, TableGen writes this difficult function for you.> So, should this not happen, or is the flag needed, or is this just a > sign that we have a really weird or buggy register model?We can handle weird, but not buggy. :-)
Reasonably Related Threads
- [LLVMdev] Problem with cross class joins in the RegisterCoalescer
- [LLVMdev] Problem with cross class joins in the RegisterCoalescer
- [LLVMdev] Problem with cross class joins in the RegisterCoalescer
- [LLVMdev] Problem with cross class joins in the RegisterCoalescer
- [LLVMdev] [PATCH] Replacing EVT:s with MVT:s (when possible)