[PATCH v2 11/15] simplify OP(((x & M') | y), K) when (M' & M) != M'

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

 



Currently, in simplify_mask_or_and(), only the cases where
(M' & M) == 0 or (M' & M) == M are simplified. However, if the
effective mask (M' & M) is different than the original inner mask
(M'), this inner mask can be replaced by the smaller effective one,
giving: OP(((x & M'') | y), K) with M'' == (M' & M)

For example, code like:
	int foo(int x, int y)
	{
		return (((x & 0xfffffff0) | y) & 0xfff);
	}

is now simplified into:
	foo:
		and.32      %r2 <- %arg1, $0xff0
		or.32       %r4 <- %r2, %arg2
		and.32      %r5 <- %r4, $0xfff
		ret.32      %r5

while previously, the mask was not reduced:
	foo:
		and.32      %r2 <- %arg1, $0xfffffff0
		...

Note: this is not a very effective simplification like directly
      removing an instruction, nevertheless the smaller mask can
      trigger other simplifications and may also be advantageous
      for a subsequent code generation phase.

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

diff --git a/simplify.c b/simplify.c
index 01e4b489a..e985a1db7 100644
--- a/simplify.c
+++ b/simplify.c
@@ -578,6 +578,11 @@ static int simplify_mask_or_and(struct instruction *insn, unsigned long long mas
 		// if (M' & M) == M: ((a & M') | b) -> (a | b)
 		return replace_pseudo(or, arg, and->src1);
 	}
+	if (nmask != omask && !multi_users(ora)) {
+		// if (M' & M) != M': AND(a, M') -> AND(a, (M' & M))
+		and->src2 = value_pseudo(nmask);
+		return REPEAT_CSE;
+	}
 	return 0;
 }
 
diff --git a/validation/optim/and-or-bf2.c b/validation/optim/and-or-bf2.c
index cccaa85bc..2296da122 100644
--- a/validation/optim/and-or-bf2.c
+++ b/validation/optim/and-or-bf2.c
@@ -14,7 +14,6 @@ void foo(struct s *p)
 /*
  * check-name: and-or-bf2
  * check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-start
 foo:
diff --git a/validation/optim/and-or-lsr2.c b/validation/optim/and-or-lsr2.c
index a0df29631..d1af0135d 100644
--- a/validation/optim/and-or-lsr2.c
+++ b/validation/optim/and-or-lsr2.c
@@ -6,7 +6,6 @@ int foo(int x, int y)
 /*
  * check-name: and-or-lsr2
  * check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-contains: and\\..*\\$0xf0fff
diff --git a/validation/optim/and-or-mask2.c b/validation/optim/and-or-mask2.c
index 6c340c7ee..cab802a66 100644
--- a/validation/optim/and-or-mask2.c
+++ b/validation/optim/and-or-mask2.c
@@ -6,7 +6,6 @@ int foo(int x, int y)
 /*
  * check-name: and-or-mask2
  * check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-contains: and\\..*\\$0xf0f
-- 
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