On Fri, May 11, 2012 at 1:54 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > Hello! > > Recently testsuite/gcc.c-torture/execute/ieee/pr50310.c started to ICE > when compiled with -O3 -mieee on alphaev68-pc-linux-gnu: > > $ ~/gcc-build-alpha/gcc/cc1 -O3 -mieee -quiet pr50310.c > pr50310.c: In function ‘foo’: > pr50310.c:31:20: internal compiler error: in > alpha_emit_conditional_move, at config/alpha/alpha.c:2649 > s3[10 * 4 + i] = __builtin_isunordered (s1[i], s2[i]) ? -1.0 : 0.0; > ^ > Please submit a full bug report, > with preprocessed source if appropriate. > See <http://gcc.gnu.org/bugs.html> for instructions. > > It turned out that UNORDERED and ORDERED RTX codes are not handled in > alpha_emit_conditional_move. Attached patch fixes this oversight. > > 2012-05-11 Uros Bizjak <ubiz...@gmail.com> > > * config/alpha/alpha.c (alpha_emit_conditional_branch): Handle > ORDERED and UNORDERED conditions. > > Patch was bootstrapped and regression tested on > alphaev68-pc-linux-gnu. OK for mainline SVN and release branches?
Oops, wrong patch was attached. Attached is the correct one. Uros.
Index: config/alpha/alpha.c =================================================================== --- config/alpha/alpha.c (revision 187394) +++ config/alpha/alpha.c (working copy) @@ -2335,7 +2335,7 @@ alpha_emit_conditional_branch (rtx operands[], enu { case EQ: case LE: case LT: case LEU: case LTU: case UNORDERED: - /* We have these compares: */ + /* We have these compares. */ cmp_code = code, branch_code = NE; break; @@ -2572,13 +2572,15 @@ alpha_emit_conditional_move (rtx cmp, enum machine switch (code) { case EQ: case LE: case LT: case LEU: case LTU: + case UNORDERED: /* We have these compares. */ cmp_code = code, code = NE; break; case NE: - /* This must be reversed. */ - cmp_code = EQ, code = EQ; + case ORDERED: + /* These must be reversed. */ + cmp_code = reverse_condition (code), code = EQ; break; case GE: case GT: case GEU: case GTU: @@ -2598,6 +2600,14 @@ alpha_emit_conditional_move (rtx cmp, enum machine gcc_unreachable (); } + if (cmp_mode == DImode) + { + if (!reg_or_0_operand (op0, DImode)) + op0 = force_reg (DImode, op0); + if (!reg_or_8bit_operand (op1, DImode)) + op1 = force_reg (DImode, op1); + } + tem = gen_reg_rtx (cmp_mode); emit_insn (gen_rtx_SET (VOIDmode, tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, @@ -2609,6 +2619,14 @@ alpha_emit_conditional_move (rtx cmp, enum machine local_fast_math = 1; } + if (cmp_mode == DImode) + { + if (!reg_or_0_operand (op0, DImode)) + op0 = force_reg (DImode, op0); + if (!reg_or_8bit_operand (op1, DImode)) + op1 = force_reg (DImode, op1); + } + /* We may be able to use a conditional move directly. This avoids emitting spurious compares. */ if (signed_comparison_operator (cmp, VOIDmode) @@ -2627,11 +2645,13 @@ alpha_emit_conditional_move (rtx cmp, enum machine switch (code) { case EQ: case LE: case LT: case LEU: case LTU: + case UNORDERED: /* We have these compares: */ break; case NE: - /* This must be reversed. */ + case ORDERED: + /* These must be reversed. */ code = reverse_condition (code); cmov_code = EQ; break;