I got FAIL: gcc.dg/torture/fp-int-convert-float16.c -Os execution test FAIL: gcc.dg/torture/fp-int-convert-float16-timode.c -Os execution test with -m32: [hjl@gnu-skx-1 gcc]$ ./xgcc -B./ -m32 /export/gnu/import/git/gitlab/x86-gcc/gcc/testsuite/gcc.dg/torture/fp-int-convert-float16.c -m32 -Os -march=i686 -mfpmath=sse -msse2 [hjl@gnu-skx-1 gcc]$ ./a.out Aborted (core dumped) [hjl@gnu-skx-1 gcc]$
Iām still trying to reduce a small testcase.
Reproduced case. #include<stdlib.h> int main (void) { static volatile unsigned int ivin, ivout; static volatile _Float16 fv1, fv2; ivin = ((unsigned int)1); fv1 = ((unsigned int)1); fv2 = ivin; ivout = fv2; if (ivout != ((unsigned int)1)) abort (); exit (0); }
during pass_expand we got (debug_insn 24 23 0 (debug_marker) "test1.c":10:3 -1 (nil)) ;; fv2.1_3 ={v} fv2; (insn 25 24 0 (set (reg:HF 84 [ fv2.1_3 ]) (mem/v/c:HF (symbol_ref:SI ("fv2.1") [flags 0x2] <var_decl 0x7f1f0ae4c000 fv2>) [2 fv2+0 S2 A16])) "test1.c":10:9 -1 (nil)) ;; _4 = (unsigned int) fv2.1_3; (insn 31 25 32 (parallel [ (set (reg:DI 94) (fix:DI (reg:SF 93))) (clobber (reg:CC 17 flags)) ]) "test1.c":10:9 -1 (nil)) But __extendhfsf2 is ommited under -Os, For -O2 expand does the right thing ;; fv2.1_3 ={v} fv2; (insn 17 16 0 (set (reg:HF 84 [ fv2.1_3 ]) (mem/v/c:HF (symbol_ref:SI ("fv2.1") [flags 0x2] <var_decl 0x7f166dab4360 fv2>) [2 fv2+0 S2 A16])) "test1.c":10:9 -1 (nil)) ;; _4 = (unsigned int) fv2.1_3; (insn 18 17 19 (set (mem:HF (reg/f:SI 79 virtual-outgoing-args) [0 S2 A32]) (reg:HF 84 [ fv2.1_3 ])) "test1.c":10:9 -1 (nil)) (call_insn/u 19 18 20 (set (reg:SF 8 st) (call (mem:QI (symbol_ref:SI ("__extendhfsf2") [flags 0x41] <function_decl 0x7f166dac5000 __extendhfsf2>) [0 S1 A8]) (const_int 16 [0x10]))) "test1.c":10:9 -1 (expr_list:REG_CALL_DECL (symbol_ref:SI ("__extendhfsf2") [flags 0x41] <function_decl 0x7f166dac5000 __extendhfsf2>) (expr_list:REG_EH_REGION (const_int -2147483648 [0xffffffff80000000]) (nil))) (expr_list (use (mem:HF (reg/f:SI 79 virtual-outgoing-args) [0 S2 A8])) (nil))) (insn 20 19 21 (set (reg:SF 93) (reg:SF 8 st)) "test1.c":10:9 -1 (expr_list:REG_EQUAL (float_extend:SF (reg:HF 84 [ fv2.1_3 ])) (nil))) (insn 21 20 22 (set (reg:V4SF 95) (vec_duplicate:V4SF (mem/u/c:SF (symbol_ref/u:SI ("*.LC3") [flags 0x2]) [0 S4 A32]))) "test1.c":10:9 7413 {vec_dupv4sf} (nil)) (insn 22 21 23 (set (reg:V4SF 94) (reg:V4SF 95)) "test1.c":10:9 -1 (expr_list:REG_EQUAL (const_vector:V4SF [ (const_double:SF 2.147483648e+9 [0x0.8p+32]) repeated x4 ]) (nil))) (insn 23 22 0 (parallel [ (set (reg:SI 85 [ _4 ]) (unsigned_fix:SI (reg:SF 93))) (use (reg:V4SF 94)) (clobber (scratch:V4SF)) (clobber (scratch:V4SF)) ]) "test1.c":10:9 -1 (expr_list:REG_EQUAL (unsigned_fix:SI (reg:SF 93)) (nil)))
After emit libcall in convert_to_mode, it failed maybe_emit_unop_insn, so all insns deleted, but from here is already overrided, it seems to be a bug. if (icode != CODE_FOR_nothing) { rtx_insn *last = get_last_insn (); if (fmode != GET_MODE (from)) from = convert_to_mode (fmode, from, 0); if (must_trunc) { rtx temp = gen_reg_rtx (GET_MODE (from)); from = expand_unop (GET_MODE (from), ftrunc_optab, from, temp, 0); } if (imode != GET_MODE (to)) target = gen_reg_rtx (imode); if (maybe_emit_unop_insn (icode, target, from, doing_unsigned ? UNSIGNED_FIX : FIX)) { if (target != to) convert_move (to, target, unsignedp); return; } delete_insns_since (last); }
The master branch has been updated by hongtao Liu <liuhongt@gcc.gnu.org>: https://gcc.gnu.org/g:93e6809459f34ca7b5928f1729246b2e9dfb3eb4 commit r12-3368-g93e6809459f34ca7b5928f1729246b2e9dfb3eb4 Author: liuhongt <hongtao.liu@intel.com> Date: Mon Sep 6 17:09:38 2021 +0800 Avoid FROM being overwritten in expand_fix. For the conversion from _Float16 to int, if the corresponding optab does not exist, the compiler will try the wider mode (SFmode here), but when floatsfsi exists but FAIL, FROM will be rewritten, which leads to a PR runtime error. gcc/ChangeLog: PR middle-end/102182 * optabs.c (expand_fix): Add from1 to avoid from being overwritten. gcc/testsuite/ChangeLog: PR middle-end/102182 * gcc.target/i386/pr101282.c: New test.
Fixed in GCC12.