From a877ba986b4c5b24ee07d59b3001d45fd5b3f834 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Thu, 21 Feb 2019 14:42:01 +0100 Subject: fix amd64 addressing mode matcher The numberer made some arranging choices when numbering arguments of an instruction, but these decisions were ignored when matching. The fix is to reconcile numbering and matching. --- amd64/isel.c | 35 +++++++++++++++-------------------- test/isel1.ssa | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 test/isel1.ssa diff --git a/amd64/isel.c b/amd64/isel.c index 2519ae5..6aea850 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -25,7 +25,7 @@ struct ANum { Ins *i; }; -static void amatch(Addr *, Ref, ANum *, Fn *, int); +static int amatch(Addr *, Ref, int, ANum *, Fn *); static int noimm(Ref r, Fn *fn) @@ -131,8 +131,8 @@ seladdr(Ref *r, ANum *an, Fn *fn) r0 = *r; if (rtype(r0) == RTmp) { - amatch(&a, r0, an, fn, 1); - if (req(a.base, r0)) + memset(&a, 0, sizeof a); + if (!amatch(&a, r0, an[r0.val].n, an, fn)) return; if (a.offset.type == CAddr) if (!req(a.base, R)) { @@ -488,18 +488,16 @@ anumber(ANum *ai, Blk *b, Con *con) } } -static void -amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top) +static int +amatch(Addr *a, Ref r, int n, ANum *ai, Fn *fn) { Ins *i; int nl, nr, t, s; Ref al, ar; - if (top) - memset(a, 0, sizeof *a); if (rtype(r) == RCon) { addcon(&a->offset, &fn->con[r.val]); - return; + return 1; } assert(rtype(r) == RTmp); i = ai[r.val].i; @@ -515,14 +513,11 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top) ar = i->arg[1]; } } - switch (ai[r.val].n) { + switch (n) { case 3: /* s * i */ - if (!top) { - a->index = al; - a->scale = fn->con[ar.val].bits.i; - } else - a->base = r; - break; + a->index = al; + a->scale = fn->con[ar.val].bits.i; + return 0; case 4: /* b + s * i */ switch (nr) { case 0: @@ -534,7 +529,7 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top) a->scale = 1; break; case 3: - amatch(a, ar, ai, fn, 0); + amatch(a, ar, nr, ai, fn); break; } r = al; @@ -544,14 +539,14 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top) if (s != -1) r = SLOT(s); a->base = r; - break; + return n || s != -1; case 2: /* constants */ case 5: /* o + s * i */ case 6: /* o + b */ case 7: /* o + b + s * i */ - amatch(a, ar, ai, fn, 0); - amatch(a, al, ai, fn, 0); - break; + amatch(a, ar, nr, ai, fn); + amatch(a, al, nl, ai, fn); + return 1; default: die("unreachable"); } diff --git a/test/isel1.ssa b/test/isel1.ssa new file mode 100644 index 0000000..879a871 --- /dev/null +++ b/test/isel1.ssa @@ -0,0 +1,24 @@ +# tests that the address matcher is not +# confused by the two multiplications + +# note: the code handling apple asm fixes +# ruins the good work of the matcher here, +# I should revisit these fixes + +export function w $f(l %i, l %j) { +@start + %off1 =l mul %i, 8 + %a_i =l add $a, %off1 + %off2 =l mul %j, 4 + %a_ij =l add %a_i, %off2 + %x =w loadsw %a_ij + ret %x +} + +# >>> driver +# int a[] = {1, 2, 3, 4}; +# extern int f(long long, long long); +# int main() { +# return !(f(0, 0) == 1 && f(0, 1) == 2 && f(1, 0) == 3 && f(1, 1) == 4); +# } +# <<< -- cgit 1.4.1