Hello!

g++.dg/other/vector-compare.C recently started to fail on
alphaev68-pc-linux-gnu with:

[uros@localhost other]$ ~/gcc-build-alpha/gcc/cc1plus -std=gnu++11
-quiet vector-compare.C
vector-compare.C: In function ‘int main()’:
vector-compare.C:26:5: internal compiler error: in
emit_cmp_and_jump_insn_1, at optabs.c:4261
 int main ()
     ^
Please submit a full bug report,
with preprocessed source if appropriate.

Prepare_cmp_insn in optabs.c expands BLKmode compares using either
cmp{mem,str,strn}_optab, or through emit_library_call_value to integer
result register, and follows with the expansion of the compare of the
result with zero. However, the code blindly assumes that the target is
able to compare resulting SImode value, which is not true in case of
alpha. Due to missing SImode compare pattern, the above assert is
triggered in emit_cmp_and_jump_1.

The patch fixes this oversight by simply expanding the comparison of
the result through generic comparison expansion code that conveniently
follows BLKmode compare expansion.

2012-09-18  Uros Bizjak  <ubiz...@gmail.com>

        * optabs.c (prepare_cmp_insn): Expand comparison of the result
        of memory block compare through generic comparison expansion code.

Patch was bootstrapped and regression tested on alphaev68-pc-linux-gnu
and x86_64-pc-linux-gnu {,-m32}.

OK for mainline and release branches?

Thanks,
Uros.
Index: optabs.c
===================================================================
--- optabs.c    (revision 191413)
+++ optabs.c    (working copy)
@@ -4087,9 +4087,13 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comp
          size = convert_to_mode (cmp_mode, size, 1);
          emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
 
-          *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
-          *pmode = result_mode;
-         return;
+         x = result;
+         y = const0_rtx;
+         mode = result_mode;
+         methods = OPTAB_LIB_WIDEN;
+         unsignedp = false;
+
+         goto result_compare;
        }
 
       if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
@@ -4109,11 +4113,15 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comp
                                        XEXP (y, 0), Pmode,
                                        size, cmp_mode);
 
-      *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
-      *pmode = result_mode;
-      return;
+      x = result;
+      y = const0_rtx;
+      mode = result_mode;
+      methods = OPTAB_LIB_WIDEN;
+      unsignedp = false;
     }
 
+ result_compare:
+
   /* Don't allow operands to the compare to trap, as that can put the
      compare and branch in different basic blocks.  */
   if (cfun->can_throw_non_call_exceptions)

Reply via email to