diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-30 14:34:34 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-09-06 02:57:20 +0200 |
| commit | 4d2a7da9858f88b629ca08cadcd956b81a7d791c (patch) | |
| tree | e785cf08123242c84f28716091853637a523efa8 /validation/linear/logical-phi0.c | |
| parent | 39dba5892bba8771e3bcdd0a5257b33ccb3189be (diff) | |
| download | sparse-dev-4d2a7da9858f88b629ca08cadcd956b81a7d791c.tar.gz | |
fix linearization of nested logical expr
The linearization of nested logical expressions is not correct
regarding the phi-nodes and their phi-sources. For example, code like:
extern int a(void); int b(void); int c(void);
static int foo(void)
{
return (a() && b()) && c();
}
gives (optimized) IR like:
foo:
phisrc.32 %phi1 <- $0
call.32 %r1 <- a
cbr %r1, .L4, .L3
.L4:
call.32 %r3 <- b
cbr %r3, .L2, .L3
.L2:
call.32 %r5 <- c
setne.32 %r7 <- %r5, $0
phisrc.32 %phi2 <- %r7
br .L3
.L3:
phi.32 %r8 <- %phi2, %phi1
ret.32 %r8
The problem can already be seen by the fact that the phi-node in L3
has 2 operands while L3 has 3 parents. There is no phi-value for L4.
The code is OK for non-nested logical expressions: linearize_cond_branch()
takes the sucess/failure BB as argument, generate the code for those
branches and there is a phi-node for each of them. However, with
nested logical expressions, one of the BB will be shared between
the inner and the outer expression. The phisrc will 'cover' one of
the BB but only one of them.
The solution is to add the phi-sources not before but after and add
one for each of the parent BB. This way, it can be guaranteed that
each parent BB has its phisrc, whatever the complexity of the sub-
expressions. With this change, the generated IR becomes:
foo:
call.32 %r2 <- a
phisrc.32 %phi1 <- $0
cbr %r2, .L4, .L3
.L4:
call.32 %r4 <- b
phisrc.32 %phi2 <- $0
cbr %r4, .L2, .L3
.L2:
call.32 %r6 <- c
setne.32 %r8 <- %r6, $0
phisrc.32 %phi3 <- %r8
br .L3
.L3:
phi.32 %r1 <- %phi1, %phi2, %phi3
ret.32 %r1
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'validation/linear/logical-phi0.c')
| -rw-r--r-- | validation/linear/logical-phi0.c | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/validation/linear/logical-phi0.c b/validation/linear/logical-phi0.c index 92ba3bc5..96a47dba 100644 --- a/validation/linear/logical-phi0.c +++ b/validation/linear/logical-phi0.c @@ -45,5 +45,4 @@ static int roo(void) /* * check-name: bad-logical-phi0 * check-command: sparse -vir -flinearize=last $file - * check-known-to-fail */ |
