On 16/08/18 23:12, Luc Van Oostenryck wrote: > 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. Heh, just before reading this note, I was thinking: this is not all that good a simplification, its just a smaller mask, what gives ... :-D ATB, Ramsay Jones > > 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 >