diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-01-04 04:03:18 +0100 |
|---|---|---|
| committer | Christopher Li <sparse@chrisli.org> | 2017-02-13 09:34:45 +0800 |
| commit | 0ee83ccffa3437fa97058c7cdc28961f59476c9d (patch) | |
| tree | 93777aa6faa33beb7890058fea927cbea890bae6 | |
| parent | d8ce303b14f6c7e0c9f0ec37781404d735476d62 (diff) | |
| download | sparse-dev-0ee83ccffa3437fa97058c7cdc28961f59476c9d.tar.gz | |
volatile loads must not be simplified
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@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
| -rw-r--r-- | memops.c | 3 | ||||
| -rw-r--r-- | validation/memops-volatile.c | 21 |
2 files changed, 24 insertions, 0 deletions
@@ -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 + */ |
