On 8/10/23 07:04, Stefan Schulze Frielinghaus via Gcc-patches wrote:
In the former fix in commit 41ef5a34161356817807be3a2e51fbdbe575ae85 I
completely missed the fact that the normal form of a generated constant for a
mode with fewer bits than in HOST_WIDE_INT is a sign extended version of the
actual constant. This even holds true for unsigned constants.
Fixed by masking out the upper bits for the incoming constant and sign
extending the resulting unsigned constant.
Bootstrapped and regtested on x64 and s390x. Ok for mainline?
[ snip]
gcc/ChangeLog:
* combine.cc (simplify_compare_const): Properly handle unsigned
constants while narrowing comparison of memory and constants.
OK.
---
@@ -12051,15 +12052,15 @@ simplify_compare_const (enum rtx_code code,
machine_mode mode,
HOST_WIDE_INT_PRINT_HEX ") to (MEM %s "
HOST_WIDE_INT_PRINT_HEX ").\n", GET_MODE_NAME (int_mode),
GET_MODE_NAME (narrow_mode_iter), GET_RTX_NAME (code),
- (unsigned HOST_WIDE_INT)const_op, GET_RTX_NAME (adjusted_code),
- n);
+ (unsigned HOST_WIDE_INT) const_op & GET_MODE_MASK (int_mode),
+ GET_RTX_NAME (adjusted_code), n);
}
poly_int64 offset = (BYTES_BIG_ENDIAN
? 0
: (GET_MODE_SIZE (int_mode)
- GET_MODE_SIZE (narrow_mode_iter)));
*pop0 = adjust_address_nv (op0, narrow_mode_iter, offset);
- *pop1 = GEN_INT (n);
+ *pop1 = gen_int_mode (n, narrow_mode_iter);
return adjusted_code;
FWIW, I should definitely have caught this hunk earlier -- we've gone
the rounds in this same space (GEN_INT vs gen_int_mode) elsewhere.
Again, sorry for the long wait.
jeff