diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-09 23:50:41 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-09 23:51:02 +0100 |
commit | 55d44f307c12fe0241d0a12e1dfe0320a54510af (patch) | |
tree | dad6270b05823b876b78ec29e39e961a12a6c6f6 | |
parent | 94dbf5cc3a0789876c8c5acd937fca6c7f89900d (diff) | |
parent | b5bbdc9c3835b62c1e67bbd1b69017bb07f57823 (diff) | |
download | sparse-55d44f307c12fe0241d0a12e1dfe0320a54510af.tar.gz |
Merge branch 'optim-sel' into next
* simplify SEL(SEL(...), ...)
* simplify SEL(x == y, x, y) and friends
* simplify SEL(x, x, x) and SEL(x, 0, x)
-rw-r--r-- | simplify.c | 59 | ||||
-rw-r--r-- | validation/optim/call-inlined.c | 11 | ||||
-rw-r--r-- | validation/optim/eqne-select.c | 12 | ||||
-rw-r--r-- | validation/optim/select-constant-cond.c | 10 | ||||
-rw-r--r-- | validation/optim/select-same-args.c | 9 | ||||
-rw-r--r-- | validation/optim/select-select-true-false0.c | 10 | ||||
-rw-r--r-- | validation/optim/select-select-true-false1.c | 13 | ||||
-rw-r--r-- | validation/optim/select-select-true-true.c | 9 | ||||
-rw-r--r-- | validation/optim/select-self-zero.c | 10 |
9 files changed, 122 insertions, 21 deletions
@@ -1748,18 +1748,17 @@ static int simplify_cast(struct instruction *insn) static int simplify_select(struct instruction *insn) { pseudo_t cond, src1, src2; + struct instruction *def; cond = insn->src1; src1 = insn->src2; src2 = insn->src3; - if (constant(cond) || src1 == src2) { - pseudo_t *kill, take; - kill_use(&insn->src1); - take = cond->value ? src1 : src2; - kill = cond->value ? &insn->src3 : &insn->src2; - kill_use(kill); - return replace_with_pseudo(insn, take); - } + + if (constant(cond)) + return replace_with_pseudo(insn, cond->value ? src1 : src2); + if (src1 == src2) + return replace_with_pseudo(insn, src1); + if (constant(src1) && constant(src2)) { long long val1 = src1->value; long long val2 = src2->value; @@ -1777,10 +1776,46 @@ static int simplify_select(struct instruction *insn) return REPEAT_CSE; } } - if (cond == src2 && is_zero(src1)) { - kill_use(&insn->src1); - kill_use(&insn->src3); - return replace_with_value(insn, 0); + if (cond == src2 && is_zero(src1)) // SEL(x, 0, x) --> 0 + return replace_with_pseudo(insn, src1); + if (cond == src1 && is_zero(src2)) // SEL(x, x, 0) --> x + return replace_with_pseudo(insn, cond); + + switch (DEF_OPCODE(def, cond)) { + case OP_SET_EQ: + if (src1 == def->src1 && src2 == def->src2) + return replace_with_pseudo(insn, src2); // SEL(x==y,x,y) --> y + if (src2 == def->src1 && src1 == def->src2) + return replace_with_pseudo(insn, src2); // SEL(y==x,x,y) --> y + break; + case OP_SET_NE: + if (src1 == def->src1 && src2 == def->src2) + return replace_with_pseudo(insn, src1); // SEL(x!=y,x,y) --> x + if (src2 == def->src1 && src1 == def->src2) + return replace_with_pseudo(insn, src1); // SEL(y!=x,x,y) --> x + break; + case OP_SEL: + if (constant(def->src2) && constant(def->src3)) { + // Is the def of the conditional another select? + // And if that one results in a "zero or not", use the + // original conditional instead. + // SEL(SEL(x, C, 0), y, z) --> SEL(x, y, z) + // SEL(SEL(x, C, 0), C, 0) --> SEL(x, C, 0) == cond + // SEL(SEL(x, 0, C), y, z) --> SEL(x, z, y) + // SEL(SEL(x, C1, C2), y, z) --> y + if (!def->src3->value) { + if ((src1 == def->src2) && (src2 == def->src3)) + return replace_with_pseudo(insn, cond); + return replace_pseudo(insn, &insn->cond, def->cond); + } + if (!def->src2->value) { + switch_pseudo(insn, &insn->src2, insn, &insn->src3); + return replace_pseudo(insn, &insn->cond, def->cond); + } + // both values must be non-zero + return replace_with_pseudo(insn, src1); + } + break; } return 0; } diff --git a/validation/optim/call-inlined.c b/validation/optim/call-inlined.c index f21b3294..7f5f4e89 100644 --- a/validation/optim/call-inlined.c +++ b/validation/optim/call-inlined.c @@ -18,13 +18,6 @@ int foo(int a, int b, int p) * check-name: call-inlined * check-command: test-linearize -Wno-decl $file * - * check-output-start -foo: -.L0: - <entry-point> - select.32 %r10 <- %arg3, %arg3, $0 - ret.32 %r10 - - - * check-output-end + * check-output-ignore + * check-output-returns: %arg3 */ diff --git a/validation/optim/eqne-select.c b/validation/optim/eqne-select.c new file mode 100644 index 00000000..9dfd88b5 --- /dev/null +++ b/validation/optim/eqne-select.c @@ -0,0 +1,12 @@ +int sel_eq01(int a, int b) { return ((a == b) ? a : b) == b; } +int sel_eq10(int a, int b) { return ((a == b) ? b : a) == a; } +int sel_ne01(int a, int b) { return ((a != b) ? a : b) == a; } +int sel_ne10(int a, int b) { return ((a != b) ? b : a) == b; } + +/* + * check-name: eqne-select + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/optim/select-constant-cond.c b/validation/optim/select-constant-cond.c new file mode 100644 index 00000000..a9337e2c --- /dev/null +++ b/validation/optim/select-constant-cond.c @@ -0,0 +1,10 @@ +int t(int p, int a, int b) { return ((p == p) ? a : b) == a; } +int f(int p, int a, int b) { return ((p != p) ? a : b) == b; } + +/* + * check-name: select-constant-cond + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/optim/select-same-args.c b/validation/optim/select-same-args.c new file mode 100644 index 00000000..403af471 --- /dev/null +++ b/validation/optim/select-same-args.c @@ -0,0 +1,9 @@ +int foo(int p, int a) { return (p ? a : a) == a; } + +/* + * check-name: select-same-args + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/optim/select-select-true-false0.c b/validation/optim/select-select-true-false0.c new file mode 100644 index 00000000..4066c2da --- /dev/null +++ b/validation/optim/select-select-true-false0.c @@ -0,0 +1,10 @@ +int fw(int p, int a, int b) { return ((p ? 42 : 0) ? a : b) == ( p ? a : b); } +int bw(int p, int a, int b) { return ((p ? 0 : 42) ? a : b) == ( p ? b : a); } + +/* + * check-name: select-select-true-false0 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/optim/select-select-true-false1.c b/validation/optim/select-select-true-false1.c new file mode 100644 index 00000000..32c0364d --- /dev/null +++ b/validation/optim/select-select-true-false1.c @@ -0,0 +1,13 @@ +int foo(int p) +{ + int t = (p ? 42 : 0); + return (t ? 42 : 0) == ( p ? 42 : 0); +} + +/* + * check-name: select-select-true-false1 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/optim/select-select-true-true.c b/validation/optim/select-select-true-true.c new file mode 100644 index 00000000..c0c26fdd --- /dev/null +++ b/validation/optim/select-select-true-true.c @@ -0,0 +1,9 @@ +int foo(int p, int a, int b) { return ((p ? 42 : 43) ? a : b) == a ; } + +/* + * check-name: select-select-true-true + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/optim/select-self-zero.c b/validation/optim/select-self-zero.c new file mode 100644 index 00000000..73b3a3dc --- /dev/null +++ b/validation/optim/select-self-zero.c @@ -0,0 +1,10 @@ +int sel_self0x(int x) { return (x ? 0 : x) == 0; } +int sel_selfx0(int x) { return (x ? x : 0) == x; } + +/* + * check-name: select-self-zero + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ |