aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--simplify.c5
-rw-r--r--validation/optim/lsr-asr.c42
2 files changed, 46 insertions, 1 deletions
diff --git a/simplify.c b/simplify.c
index d9c74bae..76bd4174 100644
--- a/simplify.c
+++ b/simplify.c
@@ -590,6 +590,7 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v
break;
def = pseudo->def;
switch (def->opcode) {
+ case OP_LSR:
case OP_ASR:
if (def == insn) // cyclic DAG!
break;
@@ -600,7 +601,9 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v
if (nval > insn->size)
break;
value += nval;
- if (value >= size)
+ if (def->opcode == OP_LSR)
+ insn->opcode = OP_LSR;
+ else if (value >= size)
value = size - 1;
goto new_value;
}
diff --git a/validation/optim/lsr-asr.c b/validation/optim/lsr-asr.c
new file mode 100644
index 00000000..aee46940
--- /dev/null
+++ b/validation/optim/lsr-asr.c
@@ -0,0 +1,42 @@
+int lsrasr0(unsigned int x)
+{
+ return ((int) (x >> 15)) >> 15;
+}
+
+int lsrasr1(unsigned int x)
+{
+ return ((int) (x >> 16)) >> 15;
+}
+
+int lsrasr2(unsigned int x)
+{
+ return ((int) (x >> 16)) >> 16;
+}
+
+/*
+ * check-name: lsr-asr
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+lsrasr0:
+.L0:
+ <entry-point>
+ lsr.32 %r3 <- %arg1, $30
+ ret.32 %r3
+
+
+lsrasr1:
+.L2:
+ <entry-point>
+ lsr.32 %r7 <- %arg1, $31
+ ret.32 %r7
+
+
+lsrasr2:
+.L4:
+ <entry-point>
+ ret.32 $0
+
+
+ * check-output-end
+ */