#! /bin/sh -e # DP: Fix (neg (lt X 0)) optimization (PR rtl-optimization/33148) dir= if [ $# -eq 3 -a "$2" = '-d' ]; then pdir="-d $3" dir="$3/" elif [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi case "$1" in -patch) patch $pdir -f --no-backup-if-mismatch -p0 < $0 ;; -unpatch) patch $pdir -f --no-backup-if-mismatch -R -p0 < $0 ;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 esac exit 0 From: Jakub Jelinek Sender: gcc-patches-owner@gcc.gnu.org To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix (neg (lt X 0)) optimization (PR rtl-optimization/33148) Date: Mon, 27 Aug 2007 07:22:44 -0400 Hi! PR25600 change introduced an optimization of (neg (lt x 0)) to (ashirtrt x C), but it is not checking whether x's mode is suitable for it. As it checks that op1 is const0_rtx, I believe MODE_FLOAT or VECTOR_MODE_P modes are not a problem, CC modes can certainly appear in LT's first operand with second operand const0_rtx. So, when we optimize (neg:DI (lt:DI (reg:CC ...) (const_int 0))) we create something like (sign_extend:DI (ashirtrt:CC (reg:CC ...) (const_int 31))) which is IMHO invalid RTL, ashirtrt is documented on fixed point modes only (guess vector modes aren't listed just by omission) and so is sign_extend. Ok for 4.2/trunk? 2007-08-27 Jakub Jelinek PR rtl-optimization/33148 * simplify-rtx.c (simplify_unary_operation_1): Only optimize (neg (lt X 0)) if X has scalar int mode. * gcc.c-torture/compile/20070827-1.c: New test. --- gcc/simplify-rtx.c.jj 2007-08-27 10:15:33.000000000 +0200 +++ gcc/simplify-rtx.c 2007-08-27 12:12:51.000000000 +0200 @@ -583,7 +583,8 @@ simplify_unary_operation_1 (enum rtx_cod /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */ /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */ if (GET_CODE (op) == LT - && XEXP (op, 1) == const0_rtx) + && XEXP (op, 1) == const0_rtx + && SCALAR_INT_MODE_P (GET_MODE (XEXP (op, 0)))) { enum machine_mode inner = GET_MODE (XEXP (op, 0)); int isize = GET_MODE_BITSIZE (inner); --- gcc/testsuite/gcc.c-torture/compile/20070827-1.c.jj 2007-08-27 12:17:20.000000000 +0200 +++ gcc/testsuite/gcc.c-torture/compile/20070827-1.c 2007-08-27 12:15:45.000000000 +0200 @@ -0,0 +1,20 @@ +/* PR rtl-optimization/33148 */ + +int +foo (unsigned int *p, int *q, unsigned int w, unsigned int b) +{ + unsigned int i; + int mask; + + if (q[0] < q[1]) + mask = 0xff; + else + mask = 0; + + for (i = 0; 8 * i < w; i++) + { + b ^= mask; + *p++ = b; + } + return 0; +} Jakub