The function address_taken() check that the address of a variable is not used for anything else than for doing a memory access. If the function fails, it means that the address can escape and thus can be used to modify the variable indirectly and the memop simplification would then be unsafe. The function do this check by assuming that any uses by an instruction other than a load or a store can escape the address, which is true. However it doesn't take in account that if the variable's address is used, not as the address of a store, but as the value stored, then this address also escape. Fix this by adding a check that the use of the variable's address is effectively done as the address of stores & loads and not as the value stored by the memop. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- memops.c | 2 ++ validation/mem2reg/address-used00.c | 1 - validation/optim/address-used01.c | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 validation/optim/address-used01.c diff --git a/memops.c b/memops.c index 5762f4f2c..30316391e 100644 --- a/memops.c +++ b/memops.c @@ -69,6 +69,8 @@ static int address_taken(pseudo_t pseudo) struct instruction *insn = pu->insn; if (insn->bb && (insn->opcode != OP_LOAD && insn->opcode != OP_STORE)) return 1; + if (pu->userp != &insn->src) + return 1; } END_FOR_EACH_PTR(pu); return 0; } diff --git a/validation/mem2reg/address-used00.c b/validation/mem2reg/address-used00.c index f2d6c87bd..1501bc1ca 100644 --- a/validation/mem2reg/address-used00.c +++ b/validation/mem2reg/address-used00.c @@ -13,7 +13,6 @@ int foo(int **g, int j) /* * check-name: address-used00 * check-command: test-linearize -Wno-decl -fdump-ir=final $file - * check-known-to-fail * check-output-ignore * check-output-excludes: ret\\..* \\$1 */ diff --git a/validation/optim/address-used01.c b/validation/optim/address-used01.c new file mode 100644 index 000000000..6ca75ffe5 --- /dev/null +++ b/validation/optim/address-used01.c @@ -0,0 +1,19 @@ +int foo(int **g, int j) +{ + int i = 1; + int *a; + int **p; + + a = &i; + p = &a; + *p[0] = 0; + return i; +} + +/* + * check-name: address-used01 + * check-command: test-linearize -Wno-decl -fdump-ir=final $file + * check-known-to-fail + * check-output-ignore + * check-output-contains: ret\\..* \\$0 + */ -- 2.16.2 -- 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