diff options
| -rw-r--r-- | simplify.c | 35 | ||||
| -rw-r--r-- | validation/optim/binops-same-args.c | 49 |
2 files changed, 84 insertions, 0 deletions
@@ -556,6 +556,39 @@ static int simplify_constant_binop(struct instruction *insn) return REPEAT_CSE; } +static int simplify_binop_same_args(struct instruction *insn, pseudo_t arg) +{ + switch (insn->opcode) { + case OP_SET_NE: + case OP_SET_LT: case OP_SET_GT: + case OP_SET_B: case OP_SET_A: + case OP_SUB: + case OP_XOR: + return replace_with_pseudo(insn, value_pseudo(0)); + + case OP_SET_EQ: + case OP_SET_LE: case OP_SET_GE: + case OP_SET_BE: case OP_SET_AE: + return replace_with_pseudo(insn, value_pseudo(1)); + + case OP_AND: + case OP_OR: + return replace_with_pseudo(insn, arg); + + case OP_AND_BOOL: + case OP_OR_BOOL: + // simplification is correct only if the operands + // have already been compared against zero which + // is not enforced. + break; + + default: + break; + } + + return 0; +} + static int simplify_binop(struct instruction *insn) { if (dead_insn(insn, &insn->src1, &insn->src2, NULL)) @@ -567,6 +600,8 @@ static int simplify_binop(struct instruction *insn) } if (constant(insn->src2)) return simplify_constant_rightside(insn); + if (insn->src1 == insn->src2) + return simplify_binop_same_args(insn, insn->src1); return 0; } diff --git a/validation/optim/binops-same-args.c b/validation/optim/binops-same-args.c new file mode 100644 index 00000000..9285655d --- /dev/null +++ b/validation/optim/binops-same-args.c @@ -0,0 +1,49 @@ +typedef unsigned int u32; + +int ssub(int a) { return a - a; } +u32 usub(u32 a) { return a - a; } + +int sdiv(int a) { return a / a; } +u32 udiv(u32 a) { return a / a; } +int smod(int a) { return a % a; } +u32 umod(u32 a) { return a % a; } + +int seq(int a) { return a == a; } +int sne(int a) { return a != a; } +int slt(int a) { return a < a; } +int sgt(int a) { return a > a; } +int sle(int a) { return a <= a; } +int sge(int a) { return a >= a; } + +u32 ueq(u32 a) { return a == a; } +u32 une(u32 a) { return a != a; } +u32 ult(u32 a) { return a < a; } +u32 ugt(u32 a) { return a > a; } +u32 ule(u32 a) { return a <= a; } +u32 uge(u32 a) { return a >= a; } + +u32 xor(u32 a) { return a ^ a; } + +u32 ior(u32 a) { return a | a; } +u32 and(u32 a) { return a & a; } + +/* + * check-name: double-unop + * check-command: test-linearize -Wno-decl $file + * check-output-ignore + * + * check-output-excludes: sub\\. + * check-output-contains: divs\\. + * check-output-contains: divu\\. + * check-output-contains: mods\\. + * check-output-contains: modu\\. + * check-output-excludes: seteq\\. + * check-output-excludes: setne\\. + * check-output-excludes: set[gl]t\\. + * check-output-excludes: set[gl]e\\. + * check-output-excludes: set[ab]\\. + * check-output-excludes: set[ab]e\\. + * check-output-excludes: xor\\. + * check-output-excludes: or\\. + * check-output-excludes: and\\. + */ |
