Sebastian Pop
2012-Jun-01 16:19 UTC
[LLVMdev] Predicate registers/condition codes question
Salut Ivan, On Fri, Jun 1, 2012 at 7:22 AM, Ivan Llopard <ivanllopard at gmail.com> wrote:> Hi Sebastian, > > Le 25/05/2012 18:54, Sebastian Pop a écrit : >> On Thu, May 24, 2012 at 5:40 PM, Sebastian Pop<spop at codeaurora.org> wrote: >>> On Thu, May 24, 2012 at 5:06 PM, Hal Finkel<hfinkel at anl.gov> wrote: >>>> Sebastian, >>>> >>>> First, it might be useful to look at what is done in the PowerPC >>>> backend. PPC also has condition registers that are larger than the >>>> 1-bit conditional results, and it defines 1-bit subregisters in >>>> addition to the larger condition registers. The spill-restore code ends >>>> up being more complicated, but that, perhaps, is a separate issue. [To >>>> be clear, I am not advocating for (or against) this solution even if it >>>> would work for you]. >>> Ok, thanks for the pointer, I'll go read in the PPC bits. >> I see that PPC has its condition registers CRRC as i32, and that PPC >> also has general purpose i32 registers GPRC, so the situation is slightly >> different than on Hexagon, where there are no general purpose registers >> of the same size as the predicate registers: i8. >> >> So on PPC it is "safe" to promote from i1 to i32 and to "allow confusion" >> between the promoted i32 and the existing operations that were using i32: >> as we can always select between a CR and a GPR following the op type. >> >> On Hexagon, if type legalization promotes i1 into i8, that would create >> this confusion between the i8 ops existing before legalization and the >> newly promoted ones. Then as Ivan was suggesting, we will have to >> provide custom expansion to promote the "illegal" ops on i8 on almost >> all the operations, except logical ops. > > I think there is also another (and cleaner) workaround, a kind of > operation-based type promotion of __illegal__ types. > This can be done by simply setting the operation with illegal type > result to have a custom expander, for example: > > setOperationAction(ISD::AND, MVT::i1, Custom) >I was exploring something similar using exactly this function.> See LowerOperationWrapper() & ReplaceNodeResults() hooks in > TargetLowering. If you make this work only on logical ops, the rest will > get automatically promoted by setting the promotion of i1 to be i32 byI think I was not clear enough in my past emails, so let me try again: As I am specifying that predicate registers are i8, LLVM considers i8 to be a legal type. i1 is then automatically promoted to the next larger legal type, that is i8: this is the correct behavior. The problem is that the existing integer arithmetic operations on i8 are not legal to be executed on the predicate registers (i.e., clang would generate an i8 expression for the addition of two char variables.) Hexagon cannot do integer arithmetic operations using the predicate registers. The addition of two char variables has to be promoted to the next available integer arithmetic register: that is i32. Because LLVM automatically legalizes i8 types, it considers all operations to be legal on i8 (i.e., both integer and boolean arithmetic.) So the solution that I was investigating looks like this: for (unsigned int i = 0; i < ISD::BUILTIN_OP_END; ++i) { switch (i) { // By default all operations on i8 have to be promoted to i32. default: setOperationAction(i, MVT::i8, Custom); break; // Only the following operations are legal on i8 predicates. case ISD::AND: case ISD::OR: case ISD::XOR: case ISD::SETCC: case ISD::SIGN_EXTEND: break; } } and promote all i8 to i32 in HexagonTargetLowering::LowerOperation> default. The latter will require a little hack though... > I hope this helps.Thanks again for your ideas and guidance: very much appreciated. Sebastian -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum
Salut Sebastian! On 01/06/2012 18:19, Sebastian Pop wrote:> Salut Ivan, > > On Fri, Jun 1, 2012 at 7:22 AM, Ivan Llopard<ivanllopard at gmail.com> wrote: >> Hi Sebastian, >> >> Le 25/05/2012 18:54, Sebastian Pop a écrit : >>> On Thu, May 24, 2012 at 5:40 PM, Sebastian Pop<spop at codeaurora.org> wrote: >>>> On Thu, May 24, 2012 at 5:06 PM, Hal Finkel<hfinkel at anl.gov> wrote: >>>>> Sebastian, >>>>> >>>>> First, it might be useful to look at what is done in the PowerPC >>>>> backend. PPC also has condition registers that are larger than the >>>>> 1-bit conditional results, and it defines 1-bit subregisters in >>>>> addition to the larger condition registers. The spill-restore code ends >>>>> up being more complicated, but that, perhaps, is a separate issue. [To >>>>> be clear, I am not advocating for (or against) this solution even if it >>>>> would work for you]. >>>> Ok, thanks for the pointer, I'll go read in the PPC bits. >>> I see that PPC has its condition registers CRRC as i32, and that PPC >>> also has general purpose i32 registers GPRC, so the situation is slightly >>> different than on Hexagon, where there are no general purpose registers >>> of the same size as the predicate registers: i8. >>> >>> So on PPC it is "safe" to promote from i1 to i32 and to "allow confusion" >>> between the promoted i32 and the existing operations that were using i32: >>> as we can always select between a CR and a GPR following the op type. >>> >>> On Hexagon, if type legalization promotes i1 into i8, that would create >>> this confusion between the i8 ops existing before legalization and the >>> newly promoted ones. Then as Ivan was suggesting, we will have to >>> provide custom expansion to promote the "illegal" ops on i8 on almost >>> all the operations, except logical ops. >> >> I think there is also another (and cleaner) workaround, a kind of >> operation-based type promotion of __illegal__ types. >> This can be done by simply setting the operation with illegal type >> result to have a custom expander, for example: >> >> setOperationAction(ISD::AND, MVT::i1, Custom) >> > > I was exploring something similar using exactly this function. > >> See LowerOperationWrapper()& ReplaceNodeResults() hooks in >> TargetLowering. If you make this work only on logical ops, the rest will >> get automatically promoted by setting the promotion of i1 to be i32 by > > I think I was not clear enough in my past emails, so let me try again: > > As I am specifying that predicate registers are i8, LLVM considers i8 > to be a legal type. i1 is then automatically promoted to the next > larger legal type, that is i8: this is the correct behavior.Right. I've mixed things up. I thought you wanted to 'track' i1->i8 promotions to make the difference between the operations coming directly from clang in i8 and the promoted ones.> > The problem is that the existing integer arithmetic operations on i8 > are not legal to be executed on the predicate registers (i.e., clang > would generate an i8 expression for the addition of two char > variables.) Hexagon cannot do integer arithmetic operations using the > predicate registers. The addition of two char variables has to be > promoted to the next available integer arithmetic register: that is > i32. Because LLVM automatically legalizes i8 types, it considers all > operations to be legal on i8 (i.e., both integer and boolean arithmetic.) > > So the solution that I was investigating looks like this: > > for (unsigned int i = 0; i< ISD::BUILTIN_OP_END; ++i) { > switch (i) { > // By default all operations on i8 have to be promoted to i32. > default: > setOperationAction(i, MVT::i8, Custom); > break; > > // Only the following operations are legal on i8 predicates. > case ISD::AND: > case ISD::OR: > case ISD::XOR: > case ISD::SETCC: > case ISD::SIGN_EXTEND: > break; > } > } > > and promote all i8 to i32 in HexagonTargetLowering::LowerOperationThat's hard work! Why don't you call it with "Promote" instead of "Custom" and let the Legalizer do the job? Does it not work? Ivan> >> default. The latter will require a little hack though... >> I hope this helps. > > Thanks again for your ideas and guidance: very much appreciated. > > Sebastian > -- > Qualcomm Innovation Center, Inc is a member of Code Aurora Forum
Hi,>> The problem is that the existing integer arithmetic operations on i8 >> are not legal to be executed on the predicate registers (i.e., clang >> would generate an i8 expression for the addition of two char >> variables.) Hexagon cannot do integer arithmetic operations using the >> predicate registers.so what can you actually do with predicate registers? Ciao, Duncan. The addition of two char variables has to be>> promoted to the next available integer arithmetic register: that is >> i32. Because LLVM automatically legalizes i8 types, it considers all >> operations to be legal on i8 (i.e., both integer and boolean arithmetic.) >> >> So the solution that I was investigating looks like this: >> >> for (unsigned int i = 0; i< ISD::BUILTIN_OP_END; ++i) { >> switch (i) { >> // By default all operations on i8 have to be promoted to i32. >> default: >> setOperationAction(i, MVT::i8, Custom); >> break; >> >> // Only the following operations are legal on i8 predicates. >> case ISD::AND: >> case ISD::OR: >> case ISD::XOR: >> case ISD::SETCC: >> case ISD::SIGN_EXTEND: >> break; >> } >> } >> >> and promote all i8 to i32 in HexagonTargetLowering::LowerOperation > > That's hard work! Why don't you call it with "Promote" instead of > "Custom" and let the Legalizer do the job? Does it not work? > > > Ivan > >> >>> default. The latter will require a little hack though... >>> I hope this helps. >> >> Thanks again for your ideas and guidance: very much appreciated. >> >> Sebastian >> -- >> Qualcomm Innovation Center, Inc is a member of Code Aurora Forum > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Sebastian Pop
2012-Jun-04 16:22 UTC
[LLVMdev] Predicate registers/condition codes question
On Sun, Jun 3, 2012 at 7:11 AM, Ivan Llopard <ivanllopard at gmail.com> wrote:>> So the solution that I was investigating looks like this: >> >> for (unsigned int i = 0; i< ISD::BUILTIN_OP_END; ++i) { >> switch (i) { >> // By default all operations on i8 have to be promoted to i32. >> default: >> setOperationAction(i, MVT::i8, Custom); >> break; >> >> // Only the following operations are legal on i8 predicates. >> case ISD::AND: >> case ISD::OR: >> case ISD::XOR: >> case ISD::SETCC: >> case ISD::SIGN_EXTEND: >> break; >> } >> } >> >> and promote all i8 to i32 in HexagonTargetLowering::LowerOperation > > That's hard work!Indeed, that was my concern as well: that's why I tried to avoid using i8 for predicates and use p8, but now I know that is a dead-end.> Why don't you call it with "Promote" instead of > "Custom" and let the Legalizer do the job? Does it not work?I tried this, and the legalizer will happily say that i8 is a legal type and just return the exact same node: this is because we declared that Hexagon has a register for i8, that makes i8 legal for all promotions. Sebastian -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum
Seemingly Similar Threads
- [LLVMdev] Predicate registers/condition codes question
- [LLVMdev] Predicate registers/condition codes question
- [LLVMdev] Predicate registers/condition codes question
- [LLVMdev] Predicate registers/condition codes question
- [LLVMdev] Predicate registers/condition codes question