We can enter simplify_plus_minus with integer vector mode operands and thus we shouldn't use constm1_rtx when canonicalizing ~a but CONSTM1_RTX (mode).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2012-02-08 Richard Guenther <rguent...@suse.de> PR rtl-optimization/52170 * simplify-rtx.c (simplify_plus_minus): Use CONSTM1_RTX to properly handle integer vector modes. * gcc.dg/torture/pr52170.c: New testcase. Index: gcc/simplify-rtx.c =================================================================== *** gcc/simplify-rtx.c (revision 183997) --- gcc/simplify-rtx.c (working copy) *************** simplify_plus_minus (enum rtx_code code, *** 3947,3953 **** /* ~a -> (-a - 1) */ if (n_ops != 7) { ! ops[n_ops].op = constm1_rtx; ops[n_ops++].neg = this_neg; ops[i].op = XEXP (this_op, 0); ops[i].neg = !this_neg; --- 3947,3953 ---- /* ~a -> (-a - 1) */ if (n_ops != 7) { ! ops[n_ops].op = CONSTM1_RTX (mode); ops[n_ops++].neg = this_neg; ops[i].op = XEXP (this_op, 0); ops[i].neg = !this_neg; Index: gcc/testsuite/gcc.dg/torture/pr52170.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr52170.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr52170.c (revision 0) *************** *** 0 **** --- 1,17 ---- + /* { dg-do compile } */ + + typedef unsigned char uint8_t ; + typedef unsigned long uint32_t; + void f0a(uint32_t * result, uint32_t * arg1) + { + int idx; + for (idx=0;idx<96;idx += 1) + { + uint8_t temp_5; + uint8_t temp_6; + + temp_5 = ~(*arg1); + temp_6 = (*arg1) + 1 - temp_5; + result[idx] = temp_6; + } + }