aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--simplify.c14
-rw-r--r--validation/optim/and-lsr.c1
2 files changed, 14 insertions, 1 deletions
diff --git a/simplify.c b/simplify.c
index ab715aad..455b1a04 100644
--- a/simplify.c
+++ b/simplify.c
@@ -590,6 +590,7 @@ static int simplify_or_lsr(struct instruction *insn, pseudo_t src, pseudo_t othe
static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long value)
{
struct instruction *def;
+ unsigned long long mask;
unsigned long long nval;
unsigned int size;
pseudo_t src2;
@@ -643,6 +644,19 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v
if (value >= size)
goto zero;
switch(DEF_OPCODE(def, pseudo)) {
+ case OP_AND:
+ // replace (A & M) >> S
+ // by (A >> S) & (M >> S)
+ if (!constant(def->src2))
+ break;
+ if (nbr_users(pseudo) > 1)
+ break;
+ mask = def->src2->value;
+ def->opcode = OP_LSR;
+ def->src2 = insn->src2;
+ insn->opcode = OP_AND;
+ insn->src2 = value_pseudo(mask >> value);
+ return REPEAT_CSE;
case OP_LSR:
goto case_shift_shift;
case OP_OR:
diff --git a/validation/optim/and-lsr.c b/validation/optim/and-lsr.c
index df6b72f3..439eb822 100644
--- a/validation/optim/and-lsr.c
+++ b/validation/optim/and-lsr.c
@@ -8,7 +8,6 @@ unsigned int foo(unsigned int x)
/*
* check-name: and-lsr
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-contains: and\\..*\\$15