diff mbox

[03/17] big-shift: do not evaluate negative or over-sized shifts

Message ID 20180721143322.99163-4-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show

Commit Message

Luc Van Oostenryck July 21, 2018, 2:33 p.m. UTC
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@gmail.com>
---
 simplify.c | 6 ++++++
 1 file changed, 6 insertions(+)
diff mbox

Patch

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 */