diff options
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 0f17559..88495a6 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -10975,14 +10975,22 @@ simplify_comparison (code, pop0, pop1) tmode = GET_MODE_WIDER_MODE (tmode)) if (have_insn_for (COMPARE, tmode)) { + int zero_extended; + /* If the only nonzero bits in OP0 and OP1 are those in the narrower mode and this is an equality or unsigned comparison, we can use the wider mode. Similarly for sign-extended values, in which case it is true for all comparisons. */ - if (((code == EQ || code == NE - || code == GEU || code == GTU || code == LEU || code == LTU) - && (nonzero_bits (op0, tmode) & ~GET_MODE_MASK (mode)) == 0 - && (nonzero_bits (op1, tmode) & ~GET_MODE_MASK (mode)) == 0) + zero_extended = ((code == EQ || code == NE + || code == GEU || code == GTU + || code == LEU || code == LTU) + && (nonzero_bits (op0, tmode) + & ~GET_MODE_MASK (mode)) == 0 + && ((GET_CODE (op1) == CONST_INT + || (nonzero_bits (op1, tmode) + & ~GET_MODE_MASK (mode)) == 0))); + + if (zero_extended || ((num_sign_bit_copies (op0, tmode) > GET_MODE_BITSIZE (tmode) - GET_MODE_BITSIZE (mode)) && (num_sign_bit_copies (op1, tmode) @@ -10999,6 +11007,8 @@ simplify_comparison (code, pop0, pop1) XEXP (op0, 1))); op0 = gen_lowpart_for_combine (tmode, op0); + if (zero_extended && GET_CODE (op1) == CONST_INT) + op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode)); op1 = gen_lowpart_for_combine (tmode, op1); break; } |