diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-07-08 10:24:01 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-07 13:31:12 +0200 |
| commit | 0908755d71eec16da5ab1f9ef1019bdcab4f1857 (patch) | |
| tree | 11625be82f448c00a3311d4dfa972f92cf0b6812 /linearize.c | |
| parent | 7347750afb894047b5145637cdebd1613c33d64a (diff) | |
| download | sparse-dev-0908755d71eec16da5ab1f9ef1019bdcab4f1857.tar.gz | |
fix instruction size & type in linearize_inc_dec()
If the ++ or -- operator is used on a bitfield, the addition or
subtraction is done with the size of the bitfield. So code like:
struct {
int f:3;
} s;
...
s->f++;
will generate intermediate code like:
add.3 %r <- %a, $1
This is not incorrect from the IR point of view but CPUs have
only register-sized instructions, like 'add.32'. So, these
odd-sized instruction have one or two implicit masking/extend
that should better make explicit.
Fix this by casting to and from the base type when these operators
are used on bitfields.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'linearize.c')
| -rw-r--r-- | linearize.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/linearize.c b/linearize.c index 9a6fd250..3cb44847 100644 --- a/linearize.c +++ b/linearize.c @@ -1119,7 +1119,11 @@ static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr one = add_setfval(ep, expr->ctype, expr->op_value); else one = value_pseudo(expr->op_value); - new = add_binary_op(ep, expr->ctype, op, old, one); + if (ad.btype != ad.type) + old = cast_pseudo(ep, old, ad.type, ad.btype); + new = add_binary_op(ep, ad.btype, op, old, one); + if (ad.btype != ad.type) + new = cast_pseudo(ep, new, ad.btype, ad.type); linearize_store_gen(ep, new, &ad); return postop ? old : new; } |
