[bugs] Three x86-64 ICEs

Jan Hubicka jh@suse.cz
Wed Jan 9 04:58:00 GMT 2002


> I have three small testcases here, that all gives an ICE. These are afaics 
> the only thing keeping me from compiling X now. The first one is there with 
> just -O2 (-O is Ok), and the last two needs -O2 -mcmodel=medium to trigger.
> 
> The first one:
> 
> --- Problem.c ---:
> float f;
> 
> int unknown(void);
> 
> void problem(void)
> {
>     float f1, f2, f3;
> 
>     for(;unknown();)
>       {
> 	  if( f1 > f3 )
>               f3 = f1;
>       }
> 
>     f = f2 ? f2 + 0.5 : f3 + 0.5;
> }
> --- *** ---
> 
> bo@pluto /tmp> /opt/x86-64/bin/x86_64-unknown-linux-gcc -O2 -v problem.c
> Reading specs from /opt/x86-64/lib/gcc-lib/x86_64-unknown-linux/3.1/specs
> Configured with: ../gcc/configure --prefix=/opt/x86-64 
> --target=x86_64-unknown-linux --enable-languages=c,c++
> Thread model: single
> gcc version 3.1 20020108 (experimental)
>  /opt/x86-64/lib/gcc-lib/x86_64-unknown-linux/3.1/cc1 -lang-c -v -D__GNUC__=3 
> -D__GNUC_MINOR__=1 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ 
> -D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__OPTIMIZE__ 
> -D__STDC_HOSTED__=1 -Acpu=x86_64 -Amachine=x86_64 -D__x86_64 -D__x86_64__ 
> -D__SIZE_TYPE__=unsigned long int -D__PTRDIFF_TYPE__=long int 
> -D__tune_athlon__ -D__tune_athlon_sse__ -D__LONG_MAX__=9223372036854775807L 
> problem.c -quiet -dumpbase problem.c -O2 -version -o /tmp/ccJwxSR8.s
> GNU CPP version 3.1 20020108 (experimental) (cpplib) (x86-64 Linux/ELF)
> GNU C version 3.1 20020108 (experimental) (x86_64-unknown-linux)
>         compiled by GNU C version 2.95.3 20010315 (SuSE).
> ignoring nonexistent directory "/opt/x86-64/x86_64-unknown-linux/sys-include"
> #include "..." search starts here:
> #include <...> search starts here:
>  /opt/x86-64/include
>  /opt/x86-64/lib/gcc-lib/x86_64-unknown-linux/3.1/include
>  /opt/x86-64/x86_64-unknown-linux/include
> End of search list.
> problem.c: In function `problem':
> problem.c:16: could not split insn
> (insn:TI 95 108 111 (parallel[
>             (set (reg:SF 8 st(0))
>                 (if_then_else:SF (gt (reg:SF 8 st(0))
>                         (mem:SF (plus:DI (reg/f:DI 7 rsp)
>                                 (const_int 16 [0x10])) [4 f1 S4 A32]))
>                     (reg:SF 8 st(0))
>                     (mem:SF (plus:DI (reg/f:DI 7 rsp)
>                             (const_int 16 [0x10])) [4 f1 S4 A32])))
>             (clobber (reg:CC 17 flags))
>         ] ) 629 {*maxsf} (insn_list 108 (nil))
>     (expr_list:REG_UNUSED (reg:CC 17 flags)
>         (nil)))
> problem.c:16: Internal compiler error in final_scan_insn, at final.c:2627
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.
> 
> 
> 
> Number two (-v will not be included because no new info is there):
> 
> --- mpcnst.i ---:
> static void boo(float *inp, unsigned char *outp)
> {
>     float inval, olm1;
>     while (1)
>     {
> 	if ((inval = *inp++) > olm1)
> 	    inval = olm1;
> 	else if (inval < 0)
> 	    inval = (float) 0;
> 	*outp++ = (unsigned char) inval;
>     }
> }
> --- *** ---
> 
> bo@pluto /tmp> /opt/x86-64/bin/x86_64-unknown-linux-gcc -O2 -mcmodel=medium 
> mpcnst.i
> mpcnst.i: In function `boo':
> mpcnst.i:12: could not split insn
> (insn 120 45 150 (parallel[
>             (set (reg:SF 8 st(0))
>                 (if_then_else:SF (gt (reg/v:SF 8 st(0) [60])
>                         (mem/u/f:SF (reg/f:DI 1 rdx [65]) [4 S4 A32]))
>                     (reg:SF 8 st(0))
>                     (mem/u/f:SF (reg/f:DI 1 rdx [65]) [4 S4 A32])))
>             (clobber (reg:CC 17 flags))
>         ] ) 629 {*maxsf} (nil)
>     (expr_list:REG_UNUSED (reg:CC 17 flags)
>         (nil)))
> mpcnst.i:12: Internal compiler error in final_scan_insn, at final.c:2627
> 
> 
> 
> The last one might be the same as above. I found it while trying to cut down 
> the size of number two:
> 
> --- mpcnst2.i ---:
> static void boo(float *inp, unsigned char *outp)
> {
>     float inval, olm1;
>     while (1)
>     {
> 	*outp++ = (unsigned char) inval;
>     }
> }
> --- *** ---
> 
> bo@pluto /tmp> /opt/x86-64/bin/x86_64-unknown-linux-gcc -O2 -mcmodel=medium 
> mpcnst2.i
> mpcnst2.i: In function `boo':
> mpcnst2.i:8: unrecognizable insn:
> (insn 87 46 83 (set (reg:SF 8 st(0))
>         (mem/u/f:SF (symbol_ref/u:DI ("*.LC0")) [4 S4 A32])) -1 (nil)
>     (nil))
> mpcnst2.i:8: Internal compiler error in insn_default_length, at 
> insn-attrtab.c:356
> 
> Bo.

Hi,
this patch fixes all 3 problems and bootstraps/regtest on i386.
The first two are caused by min/max patterns mistakely allowing memory
for i387 cmoves and the second is caused by the trick saying gcc that
constant operands are allowed for fp loads to allow better simplifications.
I simply prohibit them for medium code model where address needs to be
loaded to reg first due to lack of absolute fp loads.

I am also fixing fop_df pattern that may cause i387 register usage when
fp extension is present hurting performance.

Honza

Mit Jan  9 13:43:51 CET 2002  Jan Hubicka  <jh@suse.cz>
	* i386.md (mov?f): Avoid the fake const double trick for medium
	memory model.
	(min?f*/max?f*): Prohibit memory operands for i387 variant.
	(fop_df_4): Disable for SSE compilation.

Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.325
diff -c -3 -p -r1.325 i386.md
*** i386.md	2002/01/03 05:04:26	1.325
--- i386.md	2002/01/09 12:43:38
***************
*** 2718,2723 ****
--- 2718,2724 ----
  	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
+        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
         || GET_CODE (operands[1]) != CONST_DOUBLE
         || memory_operand (operands[0], SFmode))" 
  {
***************
*** 2893,2898 ****
--- 2894,2900 ----
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
     && (reload_in_progress || reload_completed
+        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
         || GET_CODE (operands[1]) != CONST_DOUBLE
         || memory_operand (operands[0], DFmode))" 
  {
***************
*** 2950,2955 ****
--- 2952,2958 ----
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
     && (reload_in_progress || reload_completed
+        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
         || GET_CODE (operands[1]) != CONST_DOUBLE
         || memory_operand (operands[0], DFmode))" 
  {
***************
*** 3253,3258 ****
--- 3256,3262 ----
     && optimize_size
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
+        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
         || memory_operand (operands[0], TFmode))" 
  {
    switch (which_alternative)
***************
*** 3346,3351 ****
--- 3350,3356 ----
     && !optimize_size
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
+        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
         || memory_operand (operands[0], TFmode))" 
  {
    switch (which_alternative)
***************
*** 14132,14138 ****
  	(match_operator:DF 3 "binary_fp_operator"
  	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
  	    (match_operand:DF 2 "register_operand" "0,f")]))]
!   "TARGET_80387
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
    "* return output_387_binary_op (insn, operands);"
    [(set (attr "type") 
--- 14137,14143 ----
  	(match_operator:DF 3 "binary_fp_operator"
  	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
  	    (match_operand:DF 2 "register_operand" "0,f")]))]
!   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
    "* return output_387_binary_op (insn, operands);"
    [(set (attr "type") 
***************
*** 15962,15968 ****
  (define_insn "*minsf_nonieee"
    [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
  	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
! 			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
--- 15967,15973 ----
  (define_insn "*minsf_nonieee"
    [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
  	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
! 			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
***************
*** 16044,16050 ****
  (define_insn "*mindf_nonieee"
    [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
  	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
! 			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
--- 16049,16055 ----
  (define_insn "*mindf_nonieee"
    [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
  	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
! 			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
***************
*** 16115,16121 ****
  (define_insn "*maxsf"
    [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
  	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
! 			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
--- 16120,16126 ----
  (define_insn "*maxsf"
    [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
  	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
! 			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
***************
*** 16125,16131 ****
  (define_insn "*maxsf_nonieee"
    [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
  	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
! 			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
--- 16130,16136 ----
  (define_insn "*maxsf_nonieee"
    [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
  	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
! 			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
***************
*** 16195,16201 ****
  (define_insn "*maxdf"
    [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
  	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
! 			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
--- 16200,16206 ----
  (define_insn "*maxdf"
    [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
  	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
! 			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
***************
*** 16205,16211 ****
  (define_insn "*maxdf_nonieee"
    [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
  	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
! 			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]
--- 16210,16216 ----
  (define_insn "*maxdf_nonieee"
    [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
  	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
! 			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
  			 (match_dup 1)
  			 (match_dup 2)))
     (clobber (reg:CC 17))]



More information about the Gcc-patches mailing list