diff options
39 files changed, 723 insertions, 45 deletions
@@ -577,6 +577,95 @@ undef: return NULL; } +/// +// Simplifications +// ^^^^^^^^^^^^^^^ + +/// +// try to simplify OP(OR(AND(x, M'), b), K) +// @insn: the 'masking' instruction +// @mask: the mask associated to @insn (M) +// @ora: one of the OR's operands, guaranteed to be PSEUDO_REG +// @orb: the other OR's operand +// @return: 0 if no changes have been made, one or more REPEAT_* flags otherwise. +static int simplify_mask_or_and(struct instruction *insn, unsigned long long mask, + pseudo_t ora, pseudo_t orb) +{ + unsigned long long omask, nmask; + struct instruction *and = ora->def; + pseudo_t src2 = and->src2; + + if (and->opcode != OP_AND) + return 0; + if (!constant(src2)) + return 0; + omask = src2->value; + nmask = omask & mask; + if (nmask == 0) { + // if (M' & M) == 0: ((a & M') | b) -> b + return replace_pseudo(insn, &insn->src1, orb); + } + if (multi_users(insn->src1)) + return 0; // can't modify anything inside the OR + if (nmask == mask) { + struct instruction *or = insn->src1->def; + pseudo_t *arg = (ora == or->src1) ? &or->src1 : &or->src2; + // 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; +} + +/// +// try to simplify OP(OR(a, b), K) +// @insn: the 'masking' instruction +// @mask: the mask associated to @insn (M): +// @or: the OR instruction +// @return: 0 if no changes have been made, one or more REPEAT_* flags otherwise. +// +// For the @mask (M): +// * if OP(x, K) == AND(x, M), @mask M is K +// * if OP(x, K) == LSR(x, S), @mask M is (-1 << S) +// * if OP(x, K) == SHL(x, S), @mask M is (-1 >> S) +static int simplify_mask_or(struct instruction *insn, unsigned long long mask, struct instruction *or) +{ + pseudo_t src1 = or->src1; + pseudo_t src2 = or->src2; + int rc; + + if (src1->type == PSEUDO_REG) { + if ((rc = simplify_mask_or_and(insn, mask, src1, src2))) + return rc; + } + if (src2->type == PSEUDO_REG) { + if ((rc = simplify_mask_or_and(insn, mask, src2, src1))) + return rc; + } else if (src2->type == PSEUDO_VAL) { + unsigned long long oval = src2->value; + unsigned long long nval = oval & mask; + // Try to simplify: + // OP(OR(x, C), K) + if (nval == 0) { + // if (C & M) == 0: OR(x, C) -> x + return replace_pseudo(insn, &insn->src1, src1); + } + if (nval == mask) { + // if (C & M) == M: OR(x, C) -> M + return replace_pseudo(insn, &insn->src1, value_pseudo(mask)); + } + if (nval != oval && !multi_users(or->target)) { + // if (C & M) != C: OR(x, C) -> OR(x, (C & M)) + return replace_pseudo(or, &or->src2, value_pseudo(nval)); + } + } + return 0; +} + static long long check_shift_count(struct instruction *insn, unsigned long long uval) { unsigned int size = insn->size; @@ -606,18 +695,6 @@ static long long check_shift_count(struct instruction *insn, unsigned long long return sval; } -static int simplify_or_lsr(struct instruction *insn, pseudo_t src, pseudo_t other, unsigned shift) -{ - // src->def->opcode == OP_AND - pseudo_t src2 = src->def->src2; - - if (!constant(src2)) - return 0; - if (((unsigned long long) src2->value) >> shift) - return 0; - return replace_pseudo(insn, &insn->src1, other); -} - static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long value) { struct instruction *def; @@ -625,7 +702,6 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v unsigned long long nval; unsigned int size; pseudo_t src2; - pseudo_t src; if (!value) return replace_with_pseudo(insn, pseudo); @@ -697,16 +773,8 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v case OP_LSR: goto case_shift_shift; case OP_OR: - // replace ((A & M) | B) >> S - // by (B >> S) - // when (M >> S) == 0 - src = def->src1; - if (def_opcode(src) == OP_AND) - return simplify_or_lsr(insn, src, def->src2, value); - src = def->src2; - if (def_opcode(src) == OP_AND) - return simplify_or_lsr(insn, src, def->src1, value); - break; + mask = bits_mask(size - value) << value; + return simplify_mask_or(insn, mask, def); case OP_SHL: // replace ((x << S) >> S) // by (x & (-1 >> S)) @@ -740,6 +808,9 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v break; mask = bits_mask(insn->size - value) << value; goto replace_mask; + case OP_OR: + mask = bits_mask(size - value); + return simplify_mask_or(insn, mask, def); case OP_SHL: case_shift_shift: // also for LSR - LSR if (def == insn) // cyclic DAG! @@ -881,24 +952,12 @@ 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)) { @@ -906,16 +965,7 @@ static int simplify_constant_mask(struct instruction *insn, unsigned long long m 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; + return simplify_mask_or(insn, mask, def); case OP_ZEXT: osize = def->orig_type->bit_size; /* fall through */ diff --git a/validation/optim/and-or-bf0.c b/validation/optim/and-or-bf0.c new file mode 100644 index 00000000..cfaff4f2 --- /dev/null +++ b/validation/optim/and-or-bf0.c @@ -0,0 +1,24 @@ +struct s { + int f:3; +}; + +void foo(struct s *p, int a) +{ + p->f = 1; + p->f = a; +} + +void bar(struct s *p, int a) +{ + p->f = a; + p->f = 1; +} + +/* + * check-name: and-or-bf0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(3): and\\. + * check-output-pattern(2): or\\. + */ diff --git a/validation/optim/and-or-bf1.c b/validation/optim/and-or-bf1.c new file mode 100644 index 00000000..23477ff3 --- /dev/null +++ b/validation/optim/and-or-bf1.c @@ -0,0 +1,18 @@ +struct s { + int :2; + int f:3; +}; + +void foo(struct s *d, const struct s *s, int a) +{ + d->f = s->f | a; +} + +/* + * check-name: and-or-bf1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(2): and\\. + * check-output-pattern(2): or\\. + */ diff --git a/validation/optim/and-or-bf2.c b/validation/optim/and-or-bf2.c new file mode 100644 index 00000000..2296da12 --- /dev/null +++ b/validation/optim/and-or-bf2.c @@ -0,0 +1,27 @@ +struct s { + char a:3; + char b:3; + char c:2; +}; + +void foo(struct s *p) +{ + p->a = 1; + p->b = 2; + p->c = 3; +} + +/* + * check-name: and-or-bf2 + * check-command: test-linearize -Wno-decl $file + * + * check-output-start +foo: +.L0: + <entry-point> + store.8 $209 -> 0[%arg1] + ret + + + * check-output-end + */ diff --git a/validation/optim/and-or-bfs.c b/validation/optim/and-or-bfs.c new file mode 100644 index 00000000..e08b816e --- /dev/null +++ b/validation/optim/and-or-bfs.c @@ -0,0 +1,24 @@ +struct s { + signed int :2; + signed int f:3; +}; + +int bfs(struct s s, int a) +{ + s.f = a; + return s.f; +} + +/* + * check-name: and-or-bfs + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): trunc\\. + * check-output-pattern(1): sext\\. + * check-output-excludes: and\\. + * check-output-excludes: or\\. + * check-output-excludes: shl\\. + * check-output-excludes: lsr\\. + */ diff --git a/validation/optim/and-or-bfu.c b/validation/optim/and-or-bfu.c new file mode 100644 index 00000000..c9dcfc33 --- /dev/null +++ b/validation/optim/and-or-bfu.c @@ -0,0 +1,22 @@ +struct u { + unsigned int :2; + unsigned int f:3; +}; + +int bfu(struct u s, int a) +{ + s.f = a; + return s.f; +} + +/* + * check-name: and-or-bfu + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): and\\. + * check-output-excludes: or\\. + * check-output-excludes: shl\\. + * check-output-excludes: lsr\\. + */ diff --git a/validation/optim/and-or-bfx.c b/validation/optim/and-or-bfx.c new file mode 100644 index 00000000..57a54cf5 --- /dev/null +++ b/validation/optim/and-or-bfx.c @@ -0,0 +1,18 @@ +struct s { + int f:3; +}; + +void foo(struct s *p, int a, int b) +{ + p->f = a; + p->f = b; +} + +/* + * check-name: and-or-bfx + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(2): and\\. + * check-output-pattern(1): or\\. + */ diff --git a/validation/optim/and-or-constant0.c b/validation/optim/and-or-constant0.c new file mode 100644 index 00000000..dcf440f3 --- /dev/null +++ b/validation/optim/and-or-constant0.c @@ -0,0 +1,12 @@ +int foo(int x) +{ + return (x | 0xfffff000) & 0xfff; +} + +/* + * check-name: and-or-constant0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-constant1.c b/validation/optim/and-or-constant1.c new file mode 100644 index 00000000..49823d5c --- /dev/null +++ b/validation/optim/and-or-constant1.c @@ -0,0 +1,14 @@ +int foo(int x) +{ + return (x | 0x000fffff) & 0xfff; +} + +/* + * check-name: or-and-constant1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$0xfff + * check-output-excludes: and\\. + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-constant2.c b/validation/optim/and-or-constant2.c new file mode 100644 index 00000000..d7e66f9c --- /dev/null +++ b/validation/optim/and-or-constant2.c @@ -0,0 +1,13 @@ +int foo(int x) +{ + return (x | 0xfffffff0) & 0xfff; +} + +/* + * check-name: and-or-constant2 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: or\\..*\\$0xff0 + * check-output-excludes: or\\..*\\$0xfffffff0 + */ diff --git a/validation/optim/and-or-crash.c b/validation/optim/and-or-crash.c new file mode 100644 index 00000000..98a8a9b8 --- /dev/null +++ b/validation/optim/and-or-crash.c @@ -0,0 +1,5 @@ +static unsigned a(unsigned b, unsigned c) { (c << 1 | b & 1 << 1) >> 1; } + +/* + * check-name: catch crashes during AND-OR simplifications + */ diff --git a/validation/optim/and-or-lsr0.c b/validation/optim/and-or-lsr0.c new file mode 100644 index 00000000..227c5aed --- /dev/null +++ b/validation/optim/and-or-lsr0.c @@ -0,0 +1,13 @@ +int foo(int a, int b) +{ + return ((a & 0x00000fff) | b) >> 12; +} + +/* + * check-name: and-or-lsr0 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-lsr1.c b/validation/optim/and-or-lsr1.c new file mode 100644 index 00000000..bd1dbc8a --- /dev/null +++ b/validation/optim/and-or-lsr1.c @@ -0,0 +1,13 @@ +int foo(int a, int b) +{ + return ((a & 0xfffff000) | b) >> 12; +} + +/* + * check-name: and-or-lsr1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(0): and\\. + * check-output-pattern(1): or\\. + */ diff --git a/validation/optim/and-or-lsr2.c b/validation/optim/and-or-lsr2.c new file mode 100644 index 00000000..d1af0135 --- /dev/null +++ b/validation/optim/and-or-lsr2.c @@ -0,0 +1,13 @@ +int foo(int x, int y) +{ + return ((x & 0xf0ffffff) | y) >> 12; +} + +/* + * check-name: and-or-lsr2 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: and\\..*\\$0xf0fff + * check-output-excludes: and\\..*\\$0xf0ffffff + */ diff --git a/validation/optim/and-or-lsrx.c b/validation/optim/and-or-lsrx.c new file mode 100644 index 00000000..31adca92 --- /dev/null +++ b/validation/optim/and-or-lsrx.c @@ -0,0 +1,13 @@ +unsigned int foo(unsigned int x, unsigned int y, unsigned int a) +{ + return ((x & y) | (a & 0x0fff)) >> 12; +} + +/* + * check-name: and-or-lsrx + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): and\\. + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-mask.c b/validation/optim/and-or-mask.c new file mode 100644 index 00000000..46803789 --- /dev/null +++ b/validation/optim/and-or-mask.c @@ -0,0 +1,18 @@ +int foo(int a, int b) +{ + return ((a & 7) | (b & 3)) & 8; +} + +/* + * check-name: and-or-mask + * check-command: test-linearize -Wno-decl $file + * + * check-output-start +foo: +.L0: + <entry-point> + ret.32 $0 + + + * check-output-end + */ diff --git a/validation/optim/and-or-mask0.c b/validation/optim/and-or-mask0.c new file mode 100644 index 00000000..2d2245ea --- /dev/null +++ b/validation/optim/and-or-mask0.c @@ -0,0 +1,12 @@ +int foo(int a, int b) +{ + return ((a & 0xfffff000) | b) & 0xfff; +} + +/* + * check-name: and-or-mask0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-mask1.c b/validation/optim/and-or-mask1.c new file mode 100644 index 00000000..bff3a89f --- /dev/null +++ b/validation/optim/and-or-mask1.c @@ -0,0 +1,13 @@ +int foo(int a, int b) +{ + return ((a & 0x0fffffff) | b) & 0xfff; +} + +/* + * check-name: and-or-mask1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): and\\. + * check-output-pattern(1): or\\. + */ diff --git a/validation/optim/and-or-mask2.c b/validation/optim/and-or-mask2.c new file mode 100644 index 00000000..cab802a6 --- /dev/null +++ b/validation/optim/and-or-mask2.c @@ -0,0 +1,13 @@ +int foo(int x, int y) +{ + return ((x & 0xffffff0f) | y) & 0xfff; +} + +/* + * check-name: and-or-mask2 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: and\\..*\\$0xf0f + * check-output-excludes: and\\..*\\$0xffffff0f + */ diff --git a/validation/optim/and-or-mask3s.c b/validation/optim/and-or-mask3s.c new file mode 100644 index 00000000..cf264723 --- /dev/null +++ b/validation/optim/and-or-mask3s.c @@ -0,0 +1,25 @@ +#define W 3 +#define S 8 +#define M (W << S) + +static inline int fun(unsigned int x, unsigned int y) +{ + return ((x & M) | (y << S)) >> S; +} + +short foo(unsigned int x, unsigned int y) +{ + return fun(x, y) & W; +} + +/* + * check-name: and-or-mask3s + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): lsr\\. + * check-output-pattern(1): or\\. + * check-output-pattern(1): and\\. + * check-output-excludes: shl\\. + */ diff --git a/validation/optim/and-or-mask3u.c b/validation/optim/and-or-mask3u.c new file mode 100644 index 00000000..c5b6c5fa --- /dev/null +++ b/validation/optim/and-or-mask3u.c @@ -0,0 +1,25 @@ +#define W 3 +#define S 8 +#define M (W << S) + +static inline int fun(unsigned int x, unsigned int y) +{ + return ((x & M) | (y << S)) >> S; +} + +int foo(unsigned int x, unsigned int y) +{ + return fun(x, y) & W; +} + +/* + * check-name: and-or-mask3u + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): lsr\\. + * check-output-pattern(1): or\\. + * check-output-pattern(1): and\\. + * check-output-excludes: shl\\. + */ diff --git a/validation/optim/and-or-mask4.c b/validation/optim/and-or-mask4.c new file mode 100644 index 00000000..1c4bc01a --- /dev/null +++ b/validation/optim/and-or-mask4.c @@ -0,0 +1,25 @@ +#define W 3 +#define S 8 +#define M (W << S) + +static inline int fun(unsigned int x, unsigned int y) +{ + return ((x & W) | (y >> S)) << S; +} + +int foo(unsigned int x, unsigned int y) +{ + return fun(x, y) & M; +} + +/* + * check-name: and-or-mask4 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): shl\\. + * check-output-pattern(1): or\\. + * check-output-pattern(1): and\\. + * check-output-excludes: lsr\\. + */ diff --git a/validation/optim/and-or-maskx.c b/validation/optim/and-or-maskx.c new file mode 100644 index 00000000..21d44e8d --- /dev/null +++ b/validation/optim/and-or-maskx.c @@ -0,0 +1,13 @@ +int foo(int x, int y, int a) +{ + return ((x & y) | (a & 0xf000)) & 0x0fff; +} + +/* + * check-name: and-or-maskx + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(2): and\\. + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-shl0.c b/validation/optim/and-or-shl0.c new file mode 100644 index 00000000..4850b326 --- /dev/null +++ b/validation/optim/and-or-shl0.c @@ -0,0 +1,12 @@ +int foo(int a, int b) +{ + return ((a & 0xfff00000) | b) << 12; +} + +/* + * check-name: and-or-shl0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-shl1.c b/validation/optim/and-or-shl1.c new file mode 100644 index 00000000..bea22245 --- /dev/null +++ b/validation/optim/and-or-shl1.c @@ -0,0 +1,13 @@ +int foo(int a, int b) +{ + return ((a & 0x000fffff) | b) << 12; +} + +/* + * check-name: and-or-shl1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(0): and\\. + * check-output-pattern(1): or\\. + */ diff --git a/validation/optim/and-or-shl2.c b/validation/optim/and-or-shl2.c new file mode 100644 index 00000000..f5f62758 --- /dev/null +++ b/validation/optim/and-or-shl2.c @@ -0,0 +1,13 @@ +int foo(int x, int y) +{ + return ((x & 0xffffff0f) | y) << 12; +} + +/* + * check-name: and-or-shl2 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: and\\..*\\$0xfff0f + * check-output-excludes: and\\..*\\$0xffffff0f + */ diff --git a/validation/optim/and-or-shlx.c b/validation/optim/and-or-shlx.c new file mode 100644 index 00000000..ec2a2ced --- /dev/null +++ b/validation/optim/and-or-shlx.c @@ -0,0 +1,13 @@ +unsigned int foo(unsigned int x, unsigned int y, unsigned int a) +{ + return ((x & y) | (a & 0xfff00000)) << 12; +} + +/* + * check-name: and-or-shlx + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): and\\. + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-trunc0.c b/validation/optim/and-or-trunc0.c new file mode 100644 index 00000000..873cb2d5 --- /dev/null +++ b/validation/optim/and-or-trunc0.c @@ -0,0 +1,14 @@ +char foo(int x, int y) +{ + return (x & 0xff00) | y; +} + +/* + * check-name: and-or-trunc0 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: and\\. + * check-output-excludes: or\\. + */ diff --git a/validation/optim/and-or-trunc1.c b/validation/optim/and-or-trunc1.c new file mode 100644 index 00000000..84c20317 --- /dev/null +++ b/validation/optim/and-or-trunc1.c @@ -0,0 +1,13 @@ +char foo(int x, int y) +{ + return (x & 0xffff) | y; +} + +/* + * check-name: and-or-trunc1 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: and\\. + */ diff --git a/validation/optim/and-or-trunc2.c b/validation/optim/and-or-trunc2.c new file mode 100644 index 00000000..04cb57e7 --- /dev/null +++ b/validation/optim/and-or-trunc2.c @@ -0,0 +1,14 @@ +char foo(int x, int y) +{ + return (x & 0xff07) | y; +} + +/* + * check-name: and-or-trunc2 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): and\\. + * check-output-pattern(1): and\\..*\\$7 + */ diff --git a/validation/optim/and-or-truncx.c b/validation/optim/and-or-truncx.c new file mode 100644 index 00000000..47d80dae --- /dev/null +++ b/validation/optim/and-or-truncx.c @@ -0,0 +1,14 @@ +char foo(int x, int y, int b) +{ + return (x & y) | (b & 0xff00); +} + +/* + * check-name: and-or-truncx + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(1): and\\. + * check-output-excludes: or\\. + */ diff --git a/validation/optim/store-load-bitfield.c b/validation/optim/bitfield-store-load0.c index f68cb600..f68cb600 100644 --- a/validation/optim/store-load-bitfield.c +++ b/validation/optim/bitfield-store-load0.c diff --git a/validation/optim/bitfield-store-loads.c b/validation/optim/bitfield-store-loads.c new file mode 100644 index 00000000..99a0a03a --- /dev/null +++ b/validation/optim/bitfield-store-loads.c @@ -0,0 +1,24 @@ +struct s { + char :2; + char f:3; +}; + +int foo(struct s s, int a) +{ + s.f = a; + return s.f; +} + +/* + * check-name: bitfield-store-load signed + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: shl\\. + * check-output-excludes: lsr\\. + * check-output-excludes: or\\. + * check-output-excludes: [sz]ext\\. + * check-output-excludes: trunc\\. + * check-output-pattern(1): and\\. + */ diff --git a/validation/optim/bitfield-store-loadu.c b/validation/optim/bitfield-store-loadu.c new file mode 100644 index 00000000..4c289504 --- /dev/null +++ b/validation/optim/bitfield-store-loadu.c @@ -0,0 +1,22 @@ +struct s { + unsigned int :2; + unsigned int f:3; +}; + +int foo(struct s s, int a) +{ + s.f = a; + return s.f; +} + +/* + * check-name: bitfield-store-load unsigned + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: shl\\. + * check-output-excludes: lsr\\. + * check-output-excludes: or\\. + * check-output-pattern(1): and\\. + */ diff --git a/validation/optim/or-and-constant1.c b/validation/optim/or-and-constant1.c new file mode 100644 index 00000000..aa673b90 --- /dev/null +++ b/validation/optim/or-and-constant1.c @@ -0,0 +1,29 @@ +unsigned int and_or_equ(unsigned int a) +{ + return (a | 3) & 3; +} + +int and_or_eqs(int a) +{ + return (a | 3) & 3; +} + +unsigned int or_and_equ(unsigned int a) +{ + return (a & 3) | 3; +} + +int or_and_eqs(int a) +{ + return (a & 3) | 3; +} + +/* + * check-name: or-and-constant1 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-pattern(4): ret\\..*\\$3 + * check-output-excludes: or\\. + */ diff --git a/validation/optim/sh-or-and0.c b/validation/optim/sh-or-and0.c new file mode 100644 index 00000000..02f0cb03 --- /dev/null +++ b/validation/optim/sh-or-and0.c @@ -0,0 +1,20 @@ +unsigned lsr_or_and0(unsigned x, unsigned b) +{ + return (((x & 0x00000fff) | b) >> 12); +} + +unsigned shl_or_and0(unsigned x, unsigned b) +{ + return (((x & 0xfff00000) | b) << 12); +} + +/* + * check-name: sh-or-and0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): lsr\\. + * check-output-pattern(1): shl\\. + * check-output-excludes: or\\. + * check-output-excludes: and\\. + */ diff --git a/validation/optim/sh-or-and1.c b/validation/optim/sh-or-and1.c new file mode 100644 index 00000000..7b79bbf3 --- /dev/null +++ b/validation/optim/sh-or-and1.c @@ -0,0 +1,20 @@ +unsigned lsr_or_and1(unsigned x, unsigned b) +{ + return (((x & 0xfffff000) | b) >> 12); +} + +unsigned shl_or_and1(unsigned x, unsigned b) +{ + return (((x & 0x000fffff) | b) << 12); +} + +/* + * check-name: sh-or-and1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): lsr\\. + * check-output-pattern(1): shl\\. + * check-output-pattern(2): or\\. + * check-output-excludes: and\\. + */ diff --git a/validation/optim/sh-or-and2.c b/validation/optim/sh-or-and2.c new file mode 100644 index 00000000..241aeaff --- /dev/null +++ b/validation/optim/sh-or-and2.c @@ -0,0 +1,21 @@ +unsigned lsr_or_and2(unsigned x, unsigned b) +{ + return (((x & 0xf0ffffff) | b) >> 12); +} + +unsigned shl_or_and2(unsigned x, unsigned b) +{ + return (((x & 0xffffff0f) | b) << 12); +} + +/* + * check-name: sh-or-and2 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): lsr\\. + * check-output-pattern(1): shl\\. + * check-output-pattern(2): or\\. + * check-output-pattern(1): and\\..*\\$0xf0fff000 + * check-output-pattern(1): and\\..*\\$0xfff0f + */ diff --git a/validation/optim/trunc-or-shl.c b/validation/optim/trunc-or-shl.c new file mode 100644 index 00000000..70d8bd1d --- /dev/null +++ b/validation/optim/trunc-or-shl.c @@ -0,0 +1,13 @@ +char foo(int a, int b) +{ + return (a << 8) | b; +} + +/* + * check-name: trunc-or-shl + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-contains: ret\\..*%arg2 + */ |
