During simplification, an instruction is evaluated and replaced by its value when all its operands of an instruction are known to be constant. However, for shifts, not all amounts give a well defined result: * when the amount is larger or equal to the type's width * when the shift is negative Thus performing this evaluation can possibly give a different effect than what would happen if the instruction would be executed on the target machine. In one way, this doesn't really matter since it's undefined anyway. But it is desirable for the simplification to be completly deterministic. So, don't perform this evaluation and leave these undefined operations as they are (which still gives the possibility to handle them later, depending on some f-options or maybe in a target-dependent way). Note: this is largely what seems to be done by GCC. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- simplify.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/simplify.c b/simplify.c index d09ff40ec..0c0f11349 100644 --- a/simplify.c +++ b/simplify.c @@ -472,12 +472,18 @@ static pseudo_t eval_insn(struct instruction *insn) res = left % right; break; case OP_SHL: + if (ur >= size) + goto undef; res = left << right; break; case OP_LSR: + if (ur >= size) + goto undef; res = ul >> ur; break; case OP_ASR: + if (ur >= size) + goto undef; res = left >> right; break; /* Logical */ -- 2.18.0 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html