Hi! As mentioned in the PR, on the following testcase we ICE during combine. We have (subreg:V1DI (ne:DI (reg:CC flags) (const_int 0)) 0) and gen_lowpart_for_combine turns that into (ne:V1DI (reg:CC flags) (const_int 0)) which looks wrong to me, later on the if_then_else simplifications try to simplify (subreg:V1DI (const_int 1) 0) with DImode as the inner mode and native_encode_rtx ICEs. As gen_lowpart_for_combine exits early for imode == omode, I think the optimization to change the type of comparison is only useful for scalar integral modes, for say vector modes we need the element mode to be the same as well as the number of units to be meaningful, say transforming (subreg:V8QI (ne:DI (reg:CC flags) (const_int 0)) 0) into (ne:V8QI (reg:CC flags) (const_int 0)) looks completely broken to me.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-11-27 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/92510 * combine.c (gen_lowpart_for_combine): Only transform lowpart subreg of comparison into a comparison with different mode if both imode and omode are scalar integral modes. * gcc.dg/pr92510.c: New test. --- gcc/combine.c.jj 2019-11-25 11:33:41.538074339 +0100 +++ gcc/combine.c 2019-11-26 15:55:35.433676263 +0100 @@ -11808,7 +11808,9 @@ gen_lowpart_for_combine (machine_mode om /* If X is a comparison operator, rewrite it in a new mode. This probably won't match, but may allow further simplifications. */ - else if (COMPARISON_P (x)) + else if (COMPARISON_P (x) + && SCALAR_INT_MODE_P (imode) + && SCALAR_INT_MODE_P (omode)) return gen_rtx_fmt_ee (GET_CODE (x), omode, XEXP (x, 0), XEXP (x, 1)); /* If we couldn't simplify X any other way, just enclose it in a --- gcc/testsuite/gcc.dg/pr92510.c.jj 2019-11-26 16:04:17.492688012 +0100 +++ gcc/testsuite/gcc.dg/pr92510.c 2019-11-26 15:52:28.035538275 +0100 @@ -0,0 +1,16 @@ +/* PR rtl-optimization/92510 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftree-loop-vectorize -fno-forward-propagate -fno-tree-scev-cprop" } */ + +int v; + +long int +foo (long int x) +{ + signed char i; + + for (i = 0; i < 8; ++i) + x |= !!v; + + return x + i; +} Jakub