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