aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-08-07 00:53:06 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-08 09:55:12 +0200
commit616b8d3d171eb1d17a2854ff75ec1380eda4e68d (patch)
treeabf33832a1d8c2725022ffa6256e8d57fd918f08
parent52b7cd665eb13098ea8ccd45ccac2bb5b85f423d (diff)
downloadsparse-dev-616b8d3d171eb1d17a2854ff75ec1380eda4e68d.tar.gz
simplify ((x & M') | y ) & M into (y & M) when (M' & M) == 0
This is a common pattern for bitfield simplification. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--simplify.c23
-rw-r--r--validation/optim/mask-out.c1
2 files changed, 23 insertions, 1 deletions
diff --git a/simplify.c b/simplify.c
index 106b3c84..5370e4eb 100644
--- a/simplify.c
+++ b/simplify.c
@@ -775,18 +775,41 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
return 0;
}
+static int simplify_and_or_mask(struct instruction *insn, pseudo_t and, pseudo_t other, unsigned long long mask)
+{
+ struct instruction *def = and->def;
+
+ if (!constant(def->src2))
+ return 0;
+ if (def->src2->value & mask)
+ return 0;
+ return replace_pseudo(insn, &insn->src1, other);
+}
+
static int simplify_constant_mask(struct instruction *insn, unsigned long long mask)
{
pseudo_t old = insn->src1;
unsigned long long omask;
unsigned long long nmask;
struct instruction *def;
+ pseudo_t src1, src2;
int osize;
switch (DEF_OPCODE(def, old)) {
case OP_FPCMP ... OP_BINCMP_END:
osize = 1;
goto oldsize;
+ case OP_OR:
+ // Let's handle ((A & M') | B ) & M
+ // or (B | (A & M')) & M
+ // when M' & M == 0
+ src1 = def->src1;
+ src2 = def->src2;
+ if (def_opcode(src1) == OP_AND)
+ return simplify_and_or_mask(insn, src1, src2, mask);
+ if (def_opcode(src2) == OP_AND)
+ return simplify_and_or_mask(insn, src2, src1, mask);
+ break;
case OP_ZEXT:
osize = def->orig_type->bit_size;
/* fall through */
diff --git a/validation/optim/mask-out.c b/validation/optim/mask-out.c
index bf116873..ac85aec8 100644
--- a/validation/optim/mask-out.c
+++ b/validation/optim/mask-out.c
@@ -6,7 +6,6 @@ unsigned mask(unsigned a, unsigned b)
/*
* check-name: mask-out
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-excludes: %arg1