aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-07 10:56:30 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-07 12:29:13 +0100
commitc25293e689b0b408c6228676536e928e4f042dfe (patch)
tree166607fb8a064dfe226c6419bd47fc5bf5621b12
parent84bf7462ebc80b350b0d2b35156bae04b8d5feb1 (diff)
downloadsparse-c25293e689b0b408c6228676536e928e4f042dfe.tar.gz
select: simplify handling of constant cond or src1 == src2
If the operands of a select instruction are identical, then this select can be replaced by its operand. If the condition of a select is a constant, the this select can be replaced by one of its condition, depending on the truth value of the condition. This simplification is already done but: * when src1 == src2, the condition's value is tested although it may not be a constant. It's kinda OK because in all case one of the operand will be selected and both are identical but it's a bit weird and unclean. * since the instruction will be replaced, the usage of its condition and operands must be removed. This is done here but the kill_instruction() inside replace_with_pseudo() take already care of this. So, separate the two cases and simply use replace_with_pseudo() for both without bothering killing the operands. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--simplify.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/simplify.c b/simplify.c
index 20ea5f1b..20ab9b3b 100644
--- a/simplify.c
+++ b/simplify.c
@@ -1753,14 +1753,12 @@ static int simplify_select(struct instruction *insn)
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;