[PATCH v2 08/15] allow simplification of OP(((x & y) | (a & M')), C)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In simplify_mask_or(), two calls to simplify_mask_or_and() are
made: one for each operand of the OR instruction.
These two calls are guarded by a test checking the presence of
the AND instruction. If it is the case for the first operand,
the second operand is never considered for simplification,
even if no simplications has been made.

Fix this by testing the return value of simplify_and_or_mask()
and let's do the second call if no simplifications could be
done in the first one.

For example, code like:
	int foo(int x, int y, int a)
	{
		return ((a & 0xf000) | (x & y)) & 0x0fff;
	}

was expectedly simplified into:
	foo:
		and.32      %r5 <- %arg1, %arg2
		and.32      %r7 <- %r5, $0xfff
		ret.32      %r7

while the same code with the operands of the OR swaped was not:
	int foo(int x, int y, int a)
	{
		return ((x & y) | (a & 0xf000)) & 0x0fff;
	}

resulted in the non-optimized:
	foo:
		and.32      %r3 <- %arg1, %arg2
		and.32      %r5 <- %arg3, $0xf000
		or.32       %r6 <- %r3, %r5
		and.32      %r7 <- %r6, $0xfff
		ret.32      %r7

but now the simplification can also be done:
	foo:
		and.32      %r3 <- %arg1, %arg2
		and.32      %r7 <- %r3, $0xfff
		ret.32      %r7

Note: it would be simpler to unconditionally do both calls
      but this is unsafe because some of the concerned
      instructions, needed in the second call, could have
      been simplified away in the first one.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 simplify.c                      | 7 +++++--
 validation/optim/and-or-bfx.c   | 1 -
 validation/optim/and-or-lsrx.c  | 1 -
 validation/optim/and-or-maskx.c | 1 -
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/simplify.c b/simplify.c
index a9635a9fd..a01245f79 100644
--- a/simplify.c
+++ b/simplify.c
@@ -585,11 +585,14 @@ static int simplify_mask_or(struct instruction *insn, unsigned long long mask, s
 {
 	pseudo_t src1 = or->src1;
 	pseudo_t src2 = or->src2;
+	int rc;
 
 	if (def_opcode(src1) == OP_AND)
-		return simplify_mask_or_and(insn, mask, src1, src2);
+		if ((rc = simplify_mask_or_and(insn, mask, src1, src2)))
+			return rc;
 	if (def_opcode(src2) == OP_AND)
-		return simplify_mask_or_and(insn, mask, src2, src1);
+		if ((rc = simplify_mask_or_and(insn, mask, src2, src1)))
+			return rc;
 	return 0;
 }
 
diff --git a/validation/optim/and-or-bfx.c b/validation/optim/and-or-bfx.c
index ed04e2d31..57a54cf5e 100644
--- a/validation/optim/and-or-bfx.c
+++ b/validation/optim/and-or-bfx.c
@@ -11,7 +11,6 @@ void foo(struct s *p, int a, int b)
 /*
  * check-name: and-or-bfx
  * check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-pattern(2): and\\.
diff --git a/validation/optim/and-or-lsrx.c b/validation/optim/and-or-lsrx.c
index 0b7d8f445..31adca92e 100644
--- a/validation/optim/and-or-lsrx.c
+++ b/validation/optim/and-or-lsrx.c
@@ -6,7 +6,6 @@ unsigned int foo(unsigned int x, unsigned int y, unsigned int a)
 /*
  * check-name: and-or-lsrx
  * check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-pattern(1): and\\.
diff --git a/validation/optim/and-or-maskx.c b/validation/optim/and-or-maskx.c
index 497c1a60e..21d44e8d0 100644
--- a/validation/optim/and-or-maskx.c
+++ b/validation/optim/and-or-maskx.c
@@ -6,7 +6,6 @@ int foo(int x, int y, int a)
 /*
  * check-name: and-or-maskx
  * check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-pattern(2): and\\.
-- 
2.18.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux