Message ID | 20210102100934.28459-1-luc.vanoostenryck@gmail.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | RFC: problems with cast optimization at evaluation time | expand |
On Sat, Jan 2, 2021 at 2:09 AM Luc Van Oostenryck <luc.vanoostenryck@gmail.com> wrote: > > It's easy enough to add a test to only allow this on 'true' integer types > like done in the patch. We already linearize casts to different ops for the different cases (integer/pointer/fp/bool). So yeah, we should do it at that level. > Again it's easy enough to add some checks but I wonder if all this > is really worth. I agree. Remove it from the evaluation phase, and add it to the linearized SSA format instead. Note that even on RISC architectures that don't even _have_ truncated operations (ie an "add" or "not" is always done on the whole register), doing the truncation to minimal bits is worth it, because it ends up being just a "upper bits don't matter" and will remove a _lot_ of sign-extension or zero-extension crud. So I think the simplification should be done, but I agree it's done in the wrong place. Once you do it at the instruction simplification level, all of the confusion goes away, because a "cast to floating point" is a fundamentally different operation than "zero-extend integer" at that level. Linus
diff --git a/evaluate.c b/evaluate.c index 41871e18503a..843b56a0386a 100644 --- a/evaluate.c +++ b/evaluate.c @@ -337,7 +337,7 @@ static struct expression * cast_to(struct expression *old, struct symbol *type) case EXPR_PREOP: if (old->ctype->bit_size < type->bit_size) break; - if (old->op == '~') { + if (old->op == '~' && is_int_type(type) && !is_bool_type(type)) { old->ctype = type; old->unop = cast_to(old->unop, type); return old; diff --git a/validation/eval/not-cast-bool.c b/validation/eval/not-cast-bool.c new file mode 100644 index 000000000000..acd8bbf293db --- /dev/null +++ b/validation/eval/not-cast-bool.c @@ -0,0 +1,14 @@ +static _Bool foo(void) +{ + unsigned char c = 1; + _Bool b = ~c; + return b; +} + +/* + * check-name: not-cast-bool + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */ diff --git a/validation/eval/not-cast-float.c b/validation/eval/not-cast-float.c new file mode 100644 index 000000000000..d474d69bdda3 --- /dev/null +++ b/validation/eval/not-cast-float.c @@ -0,0 +1,14 @@ +static int foo(void) +{ + int i = 123; + float x = ~i; + return (x < 0); +} + +/* + * check-name: eval-bool-zext-neg + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-returns: 1 + */