https://bugs.llvm.org/show_bug.cgi?id=37073

            Bug ID: 37073
           Summary: Register allocator spills although free registers are
                    available
           Product: new-bugs
           Version: trunk
          Hardware: Other
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedb...@nondot.org
          Reporter: gergo.bar...@inria.fr
                CC: llvm-bugs@lists.llvm.org

Created attachment 20180
  --> https://bugs.llvm.org/attachment.cgi?id=20180&action=edit
input program

The attached test file contains a simple function doing elementary arithmetic,
using only local double variables, without any branching:

double fn1(double p1, double p2, double p3, double p4, double p5, double p6,
           double p7, double p8) {
  double a, b, c, d, v, e;
  a = p4 - 5 + 9 * p1 * 7;
  c = 2 - p6 + 1;
  b = 3 * p6 * 4 - (p2 + 10) * a;
  d = (8 + p3) * p5 * 5 * p7 - p4;
  v = p1 - p8 - 2 - (p8 + p2 - b) * ((p3 + 6) * c);
  e = v * p5 + d; 
  return e;
} 

Compiling it for ARMv7-A with VFPv3-D16 floating-point support generates the
following code snippet (comments mine):

    ...
    vmov.f64    d13, #4.000000e+00      @ def d13
    vmov.f64    d14, #1.000000e+01      @ def d14
    vmul.f64    d10, d10, d13           @ last use of d13
    vadd.f64    d11, d1, d14            @ last use of d14
    vmov.f64    d12, #2.000000e+00
    vmov.f64    d15, #8.000000e+00      @ def d15
    vsub.f64    d5, d12, d5
    vadd.f64    d12, d2, d15            @ last use of d15
    vmls.f64    d10, d11, d9
    vstr    d6, [sp]                    @ spill original value of d6
    vmov.f64    d6, #6.000000e+00       @ use d6 for constant 6.0
    ...

That is, at some point the constant 6.0 must be loaded into a register, and the
default allocator decides to spill d6 to accommodate this value. But just above
this code three other registers are briefly used and never touched again: d13,
d14, and d15 would all be available to accommodate the constant without causing
a spill.

(GCC doesn't have this inline spill, and it saves fewer callee-saved registers
because it does more register reuse.)

Online: https://godbolt.org/g/8ZuYbz (note: the link shows the behavior of
Clang 6.0.0, but it's the same on trunk)

Flags: --target=armv7a-eabihf -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard
-O3 -fomit-frame-pointer

Version: LLVM r328450, Clang r328447 from 2018-03-25

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to