aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-23 22:27:56 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-25 16:36:52 +0200
commiteb180d9c0f5838c6b47c63ec475f3088c775cfd3 (patch)
treec8582eb82b1e15187530672ecd49beb006b4e684
parente703906715b38a515c8d0a4815ee8e357ff1f6ba (diff)
downloadsparse-dev-eb180d9c0f5838c6b47c63ec475f3088c775cfd3.tar.gz
shift: simplify ASR(LSR(x,N),N')
Since an LSR with an in-range shift count will insert a zero in the MSB, a subsequent ASR will be equivalent to an LSR of the same count or equivalently, the combinaison the these two shifts is equivalent to a single LSR with a shift count equal to the sum of the two initial counts. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-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
+ */