memops.c:simplify_loads() tries to simplify all loads, even volatile ones. For example, on the following code: static int foo(volatile int *a, int v) { *a = v; return *a; } test-linearize returns something like: foo: store.32 %arg2 -> 0[%arg1] ret.32 %arg2 while the correct output is more like: foo: store.32 %arg2 -> 0[%arg1] load.32 %r5 <- 0[%arg1] ret.32 %r5 The fix is to simply ignore loads with the 'volatile' modifier. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- memops.c | 3 +++ validation/memops-volatile.c | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 validation/memops-volatile.c diff --git a/memops.c b/memops.c index 45bd3401..6dac1f57 100644 --- a/memops.c +++ b/memops.c @@ -99,6 +99,9 @@ static void simplify_loads(struct basic_block *bb) /* Check for illegal offsets.. */ check_access(insn); + if (insn->type->ctype.modifiers & MOD_VOLATILE) + continue; + RECURSE_PTR_REVERSE(insn, dom) { int dominance; if (!dom->bb) diff --git a/validation/memops-volatile.c b/validation/memops-volatile.c new file mode 100644 index 00000000..0f3e12ad --- /dev/null +++ b/validation/memops-volatile.c @@ -0,0 +1,21 @@ +static int foo(volatile int *a, int v) +{ + *a = v; + return *a; +} + +/* + * check-name: memops-volatile + * check-command: test-linearize $file + * + * check-output-start +foo: +.L0: + <entry-point> + store.32 %arg2 -> 0[%arg1] + load.32 %r5 <- 0[%arg1] + ret.32 %r5 + + + * check-output-end + */ -- 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