Message ID | 85ac05d7-c0f7-fbcf-f2fc-ce52a2138cc2@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | rs6000: Fix some unexpected empty split conditions | expand |
Hi! On Fri, Mar 19, 2021 at 10:46:54AM +0800, Kewen.Lin wrote: > As Segher and Mike pointed out, the define_insn_and_split should avoid > to use empty split condition if the condition for define_insn isn't empty, > otherwise it can sometimes leads to unexpected consequence. > > This patch is to fix some places like this. > > Bootstrapped/regtested on powerpc64le-linux-gnu P9 and > powerpc64-linux-gnu P8. > > Since it's in very low risk and can avoid some unexpected errors, > is it ok for trunk? or has to be for GCC12? I am curious if the splitters ever triggered where they should not have? > diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md > index 592ac90aa44..6ab71979566 100644 > --- a/gcc/config/rs6000/rs6000.md > +++ b/gcc/config/rs6000/rs6000.md > @@ -4281,7 +4281,7 @@ If you add [diff "md"] xfuncname = "^\\(define.*$" to your .git/config, the patch will show what insn this is in: > @@ -4281,7 +4281,7 @@ (define_insn_and_split "*rotldi3_insert_sf" The patch is okay for trunk. Thank you! You might want to make this error easier to detect? Maybe make define_insn_and_split raise an error if the split condition is empty but the insn condition is not? Segher
Hi Segher, Thanks for the review. on 2021/3/19 下午8:36, Segher Boessenkool wrote: > Hi! > > On Fri, Mar 19, 2021 at 10:46:54AM +0800, Kewen.Lin wrote: >> As Segher and Mike pointed out, the define_insn_and_split should avoid >> to use empty split condition if the condition for define_insn isn't empty, >> otherwise it can sometimes leads to unexpected consequence. >> >> This patch is to fix some places like this. >> >> Bootstrapped/regtested on powerpc64le-linux-gnu P9 and >> powerpc64-linux-gnu P8. >> >> Since it's in very low risk and can avoid some unexpected errors, >> is it ok for trunk? or has to be for GCC12? > > I am curious if the splitters ever triggered where they should not have? > Do you have any suggestion to catch this? I thought the regression testing probably can show something different but it didn't unfortunately. >> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md >> index 592ac90aa44..6ab71979566 100644 >> --- a/gcc/config/rs6000/rs6000.md >> +++ b/gcc/config/rs6000/rs6000.md >> @@ -4281,7 +4281,7 @@ > > If you add > > [diff "md"] > xfuncname = "^\\(define.*$" > > to your .git/config, the patch will show what insn this is in: > Thanks for the tips! >> @@ -4281,7 +4281,7 @@ (define_insn_and_split "*rotldi3_insert_sf" > > > The patch is okay for trunk. Thank you! > > You might want to make this error easier to detect? Maybe make > define_insn_and_split raise an error if the split condition is empty but > the insn condition is not? > Good idea! Is there any possible reason to write this kind of define_insn_and_split? If no (we should forbid it), I think we can add the check and raise an error if hits in gensupport.c. I'll send out a RFC once GCC12 starts. BR, Kewen
On Fri, Mar 19, 2021 at 11:50:41PM +0800, Kewen.Lin wrote: > > I am curious if the splitters ever triggered where they should not have? > > Do you have any suggestion to catch this? I thought the regression > testing probably can show something different but it didn't unfortunately. Well, you can compare the generated binaries with a compiler binary before and after the patch, for something that will match the splitters, so with a lot of float<->integer conversions for example. I usually look at cc1 or vmlinux, but those both are nice for integer code only. Maybe we should have some tool that for every define_insn finds which define_splits can possibly match it. > > You might want to make this error easier to detect? Maybe make > > define_insn_and_split raise an error if the split condition is empty but > > the insn condition is not? > > Good idea! Is there any possible reason to write this kind of > define_insn_and_split? If no (we should forbid it), I think we can add > the check and raise an error if hits in gensupport.c. > > I'll send out a RFC once GCC12 starts. There is no good reason for it. If you really want a define_insn_and_split that splits more than just that insn, you should just write the define_insn and the define_split separately. Much clearer that way. A reader does not expect a define_insn_and_split to split any other insns. (Or they should not, IMO, of course :-) ) And yes, because that might well break things for some targets, or change behaviour at least, it is a GCC 12 thing. It will be a nice cleanup though :-) Segher
Hi Segher, on 2021/3/20 上午5:58, Segher Boessenkool wrote: > On Fri, Mar 19, 2021 at 11:50:41PM +0800, Kewen.Lin wrote: >>> I am curious if the splitters ever triggered where they should not have? >> >> Do you have any suggestion to catch this? I thought the regression >> testing probably can show something different but it didn't unfortunately. > > Well, you can compare the generated binaries with a compiler binary > before and after the patch, for something that will match the splitters, > so with a lot of float<->integer conversions for example. > > I usually look at cc1 or vmlinux, but those both are nice for integer > code only. > > Maybe we should have some tool that for every define_insn finds which > define_splits can possibly match it. > Thanks for the suggestion. I did the binary comparison for SPEC2017 executables built before and after this patch on both Power8 and Power9, I still didn't see any differences, it seems hard to trigger it. Committed via r11-7756. >>> You might want to make this error easier to detect? Maybe make >>> define_insn_and_split raise an error if the split condition is empty but >>> the insn condition is not? >> >> Good idea! Is there any possible reason to write this kind of >> define_insn_and_split? If no (we should forbid it), I think we can add >> the check and raise an error if hits in gensupport.c. >> >> I'll send out a RFC once GCC12 starts. > > There is no good reason for it. If you really want a > define_insn_and_split that splits more than just that insn, you should > just write the define_insn and the define_split separately. Much > clearer that way. A reader does not expect a define_insn_and_split to > split any other insns. (Or they should not, IMO, of course :-) ) > > And yes, because that might well break things for some targets, or > change behaviour at least, it is a GCC 12 thing. It will be a nice > cleanup though :-) > Got it! Thanks for the further explanation. :) BR, Kewen
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 592ac90aa44..6ab71979566 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -4281,7 +4281,7 @@ (clobber (match_scratch:V4SF 4))] "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>" "#" - "" + "&& 1" [(parallel [(set (match_dup 5) (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF))) (clobber (match_dup 4))]) @@ -5327,7 +5327,7 @@ (clobber (match_scratch:V2DI 6 "=0,&wa"))] "TARGET_P9_MINMAX" "#" - "" + "&& 1" [(set (match_dup 6) (if_then_else:V2DI (match_dup 1) (match_dup 7) @@ -5436,7 +5436,7 @@ "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP> && can_create_pseudo_p ()" "#" - "" + "&& 1" [(pc)] { rtx dest = operands[0]; @@ -5476,7 +5476,7 @@ (clobber (match_scratch:DI 2 "=d,wa"))] "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" "#" - "" + "&& 1" [(pc)] { operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); @@ -5533,7 +5533,7 @@ (clobber (match_scratch:DI 2 "=d,wa"))] "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" "#" - "" + "&& 1" [(pc)] { rtx dest = operands[0]; @@ -5573,7 +5573,7 @@ (clobber (match_scratch:DI 2 "=d,wa"))] "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" "#" - "" + "&& 1" [(pc)] { operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); @@ -5638,7 +5638,7 @@ (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] "!TARGET_FCFID && TARGET_HARD_FLOAT" "#" - "" + "&& 1" [(pc)] { rtx lowword, highword; @@ -5728,7 +5728,7 @@ "!TARGET_FCFIDU && TARGET_HARD_FLOAT && !(TARGET_FCFID && TARGET_POWERPC64)" "#" - "" + "&& 1" [(pc)] { rtx lowword, highword; @@ -5884,7 +5884,7 @@ "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p () && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" "#" - "" + "&& 1" [(pc)] { rtx dest = operands[0]; @@ -5926,7 +5926,7 @@ "TARGET_HARD_FLOAT && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" "#" - "" + "&& 1" [(pc)] { rtx lowword; @@ -6032,7 +6032,7 @@ && TARGET_STFIWX && can_create_pseudo_p () && !TARGET_P8_VECTOR" "#" - "" + "&& 1" [(pc)] { rtx dest = operands[0]; @@ -6252,7 +6252,7 @@ && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" "#" - "" + "&& 1" [(pc)] { rtx dest = operands[0]; @@ -6285,7 +6285,7 @@ && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" "#" - "" + "&& 1" [(pc)] { rtx dest = operands[0]; @@ -8268,7 +8268,7 @@ (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" "#" - "" + "&& 1" [(pc)] { rtx lowword; diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index ad673968584..d1053ff6746 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -972,7 +972,7 @@ "@ # xxlor %x0,%x1" - "" + "&& 1" [(set (match_dup 0) (match_dup 1))] { if (reload_completed && REGNO (operands[0]) == REGNO (operands[1])) @@ -4649,7 +4649,7 @@ (clobber (match_scratch:V2DF 2 "=0,&wa"))] "VECTOR_UNIT_VSX_P (V2DFmode)" "#" - "" + "&& 1" [(const_int 0)] { rtx tmp = (GET_CODE (operands[2]) == SCRATCH) @@ -4671,7 +4671,7 @@ (clobber (match_scratch:V4SF 3 "=&wa"))] "VECTOR_UNIT_VSX_P (V4SFmode)" "#" - "" + "&& 1" [(const_int 0)] { rtx op0 = operands[0]; @@ -4719,7 +4719,7 @@ (clobber (match_scratch:DF 2 "=0,&wa"))] "BYTES_BIG_ENDIAN && VECTOR_UNIT_VSX_P (V2DFmode)" "#" - "" + "&& 1" [(const_int 0)] { rtx hi = gen_highpart (DFmode, operands[1]); @@ -4746,7 +4746,7 @@ (clobber (match_scratch:V4SF 4 "=0"))] "BYTES_BIG_ENDIAN && VECTOR_UNIT_VSX_P (V4SFmode)" "#" - "" + "&& 1" [(const_int 0)] { rtx op0 = operands[0];