Hi, Expand pass always uses sign-extend to represent constant value. For the case in the patch, a 8-bit unsigned value "252" is represented as "-4", which pass the ccmn check. After mode conversion, "-4" becomes "252", which leads to mismatch.
The patch adds another operand check after mode conversion. No make check regression with qemu. OK for trunk? Thanks! -Zhenqiang ChangeLog: 2014-11-24 Zhenqiang Chen <zhenqiang.c...@arm.com> PR target/64015 * config/aarch64/aarch64.c (aarch64_gen_ccmp_first): Recheck operand after mode conversion. (aarch64_gen_ccmp_next): Likewise. testsuite/ChangeLog: 2014-11-24 Zhenqiang Chen <zhenqiang.c...@arm.com> * gcc.target/aarch64/pr64015.c: New test. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 1809513..203d095 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -10311,7 +10311,10 @@ aarch64_gen_ccmp_first (int code, rtx op0, rtx op1) if (!aarch64_plus_operand (op1, GET_MODE (op1))) op1 = force_reg (mode, op1); - if (!aarch64_convert_mode (&op0, &op1, unsignedp)) + if (!aarch64_convert_mode (&op0, &op1, unsignedp) + /* Some negative value might be transformed into a positive one. + So need recheck here. */ + || !aarch64_plus_operand (op1, GET_MODE (op1))) return NULL_RTX; mode = aarch64_code_to_ccmode ((enum rtx_code) code); @@ -10344,7 +10347,10 @@ aarch64_gen_ccmp_next (rtx prev, int cmp_code, rtx op0, rtx op1, int bit_code) || !aarch64_ccmp_operand (op1, GET_MODE (op1))) return NULL_RTX; - if (!aarch64_convert_mode (&op0, &op1, unsignedp)) + if (!aarch64_convert_mode (&op0, &op1, unsignedp) + /* Some negative value might be transformed into a positive one. + So need recheck here. */ + || !aarch64_ccmp_operand (op1, GET_MODE (op1))) return NULL_RTX; mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code); diff --git a/gcc/testsuite/gcc.target/aarch64/pr64015.c b/gcc/testsuite/gcc.target/aarch64/pr64015.c new file mode 100644 index 0000000..eeed665 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr64015.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options " -O2 " } */ +int +test (unsigned short a, unsigned char b) +{ + return a > 0xfff2 && b > 252; +}