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)