diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index bd9443d..69d8757 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -6109,6 +6109,23 @@ simplify_context::simplify_relational_operation_1 (rtx_code code, break; } + /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */ + if (code == NE + && op1 == const0_rtx + && (op0code == TRUNCATE + || (partial_subreg_p (op0) + && subreg_lowpart_p (op0))) + && SCALAR_INT_MODE_P (mode) + && STORE_FLAG_VALUE == 1) + { + rtx tmp = XEXP (op0, 0); + if (GET_CODE (tmp) == ASHIFT + && GET_MODE (tmp) == mode + && CONST_INT_P (XEXP (tmp, 1)) + && is_int_mode (GET_MODE (op0), &int_mode) + && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1) + return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx); + } return NULL_RTX; } diff --git a/gcc/testsuite/gcc.target/i386/pr106245-1.c b/gcc/testsuite/gcc.target/i386/pr106245-1.c new file mode 100644 index 0000000..a0403e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr106245-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f(int a) +{ + return (a << 31) >> 31; +} + +/* { dg-final { scan-assembler-not "sarb" } } */ +/* { dg-final { scan-assembler-not "movsbl" } } */