In memops:find_dominating_parents(), the 'load-load optimization' (see commit cf07903a "Don't bother finding dominating loads if ...") cause some loads simplification to be missed. For example, with the following code: int foo(int *i, int *j) { *i = 6; *j = 1; do { if (*i != 6) (*i)++; (*i)++; } while (*i != *j); return *j; } test-linearize returns something like: foo: .L0: <entry-point> store.32 $6 -> 0[%arg1] store.32 $1 -> 0[%arg2] br .L1 .L1: load.32 %r4 <- 0[%arg1] setne.32 %r5 <- %r4, $6 br %r5, .L4, .L5 .L4: add.32 %r8 <- %r4, $1 store.32 %r8 -> 0[%arg1] br .L5 .L5: load.32 %r10 <- 0[%arg1] add.32 %r11 <- %r10, $1 store.32 %r11 -> 0[%arg1] load.32 %r15 <- 0[%arg2] setne.32 %r16 <- %r11, %r15 br %r16, .L1, .L6 .L6: ret.32 %r15 where we can notice that the first load in .L5 is not needed, the value could be retrieved from %r4 and %r8, like: @@ -8,15 +8,17 @@ .L1: load.32 %r4 <- 0[%arg1] setne.32 %r5 <- %r4, $6 + phisrc.32 %phi4 <- %r4 br %r5, .L4, .L5 .L4: add.32 %r8 <- %r4, $1 store.32 %r8 -> 0[%arg1] + phisrc.32 %phi5 <- %r8 br .L5 .L5: - load.32 %r10 <- 0[%arg1] + phi.32 %r10 <- %phi4, %phi5 add.32 %r11 <- %r10, $1 store.32 %r11 -> 0[%arg1] load.32 %r15 <- 0[%arg2] The fix essentially consists in reverting commit cf07903a but on memops.c's version of find_dominating_parents(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- memops.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/memops.c b/memops.c index 6dac1f57..5efdd6f2 100644 --- a/memops.c +++ b/memops.c @@ -18,12 +18,10 @@ static int find_dominating_parents(pseudo_t pseudo, struct instruction *insn, struct basic_block *bb, unsigned long generation, struct pseudo_list **dominators, - int local, int loads) + int local) { struct basic_block *parent; - if (bb_list_size(bb->parents) > 1) - loads = 0; FOR_EACH_PTR(bb->parents, parent) { struct instruction *one; struct instruction *br; @@ -41,8 +39,6 @@ static int find_dominating_parents(pseudo_t pseudo, struct instruction *insn, } if (!dominance) continue; - if (one->opcode == OP_LOAD && !loads) - continue; goto found_dominator; } END_FOR_EACH_PTR_REVERSE(one); no_dominance: @@ -50,7 +46,7 @@ no_dominance: continue; parent->generation = generation; - if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local, loads)) + if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local)) return 0; continue; @@ -124,7 +120,7 @@ static void simplify_loads(struct basic_block *bb) generation = ++bb_generation; bb->generation = generation; dominators = NULL; - if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local, 1)) { + if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) { /* This happens with initial assignments to structures etc.. */ if (!dominators) { if (local) { -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html