Message ID | YrF8N+QlxEzZtRcH@tucnak |
---|---|
State | New |
Headers | show |
Series | expand: Fix up expand_cond_expr_using_cmove [PR106030] | expand |
On Tue, 21 Jun 2022, Jakub Jelinek wrote: > Hi! > > If expand_cond_expr_using_cmove can't find a cmove optab for a particular > mode, it tries to promote the mode and perform the cmove in the promoted > mode. > > The testcase in the patch ICEs on arm because in that case we pass temp which > has the promoted mode (SImode) as target to expand_operands where the > operands have the non-promoted mode (QImode). > Later on the function uses paradoxical subregs: > if (GET_MODE (op1) != mode) > op1 = gen_lowpart (mode, op1); > > if (GET_MODE (op2) != mode) > op2 = gen_lowpart (mode, op2); > to change the operand modes. > > The following patch fixes it by passing NULL_RTX as target if it has > promoted mode. > > Bootstrapped/regtested on x86_64-linux and i686-linux and tested with cross > to arm on the testcase, ok for trunk? OK. Thanks, Richard. > 2022-06-21 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/106030 > * expr.cc (expand_cond_expr_using_cmove): Pass NULL_RTX instead of > temp to expand_operands if mode has been promoted. > > * gcc.c-torture/compile/pr106030.c: New test. > > --- gcc/expr.cc.jj 2022-06-10 21:19:12.087803729 +0200 > +++ gcc/expr.cc 2022-06-20 14:10:07.941681072 +0200 > @@ -8832,7 +8832,8 @@ expand_cond_expr_using_cmove (tree treeo > expanding_cond_expr_using_cmove = true; > start_sequence (); > expand_operands (treeop1, treeop2, > - temp, &op1, &op2, EXPAND_NORMAL); > + mode == orig_mode ? temp : NULL_RTX, &op1, &op2, > + EXPAND_NORMAL); > > if (TREE_CODE (treeop0) == SSA_NAME > && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))) > --- gcc/testsuite/gcc.c-torture/compile/pr106030.c.jj 2022-06-20 14:49:37.618142233 +0200 > +++ gcc/testsuite/gcc.c-torture/compile/pr106030.c 2022-06-20 14:49:19.016382117 +0200 > @@ -0,0 +1,16 @@ > +/* PR middle-end/106030 */ > + > +int a, b, c; > + > +char > +foo (int x, int y) > +{ > + return x * y; > +} > + > +void > +bar (void) > +{ > + char d = (foo <= b) * a; > + c = foo (2 != bar, d); > +} > > Jakub > >
--- gcc/expr.cc.jj 2022-06-10 21:19:12.087803729 +0200 +++ gcc/expr.cc 2022-06-20 14:10:07.941681072 +0200 @@ -8832,7 +8832,8 @@ expand_cond_expr_using_cmove (tree treeo expanding_cond_expr_using_cmove = true; start_sequence (); expand_operands (treeop1, treeop2, - temp, &op1, &op2, EXPAND_NORMAL); + mode == orig_mode ? temp : NULL_RTX, &op1, &op2, + EXPAND_NORMAL); if (TREE_CODE (treeop0) == SSA_NAME && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))) --- gcc/testsuite/gcc.c-torture/compile/pr106030.c.jj 2022-06-20 14:49:37.618142233 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr106030.c 2022-06-20 14:49:19.016382117 +0200 @@ -0,0 +1,16 @@ +/* PR middle-end/106030 */ + +int a, b, c; + +char +foo (int x, int y) +{ + return x * y; +} + +void +bar (void) +{ + char d = (foo <= b) * a; + c = foo (2 != bar, d); +}