[llvm-bugs] [Bug 27596] New: Additional xmm register used for nothing in one of two test cases

via llvm-bugs llvm-bugs at lists.llvm.org
Sun May 1 18:04:05 PDT 2016


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

            Bug ID: 27596
           Summary: Additional xmm register used for nothing in one of two
                    test cases
           Product: libraries
           Version: 3.5
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Loop Optimizer
          Assignee: unassignedbugs at nondot.org
          Reporter: g1mat000 at gmail.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

I think I found a bug where a register is used "for nothing"

Here's the output of the assembly with the bug:
    movaps    %xmm0, %xmm3
    mulss    %xmm3, %xmm3

    xorps    %xmm4, %xmm4  <- here
    addss    %xmm4, %xmm3

    movaps    %xmm2, %xmm5
    mulss    %xmm5, %xmm5
    addss    %xmm3, %xmm5
    movaps    %xmm1, %xmm3
    mulss    %xmm3, %xmm3
    addss    %xmm5, %xmm3
    sqrtss    %xmm3, %xmm3
    mulss    .LCPI1_0(%rip), %xmm3
    movss    .LCPI1_1(%rip), %xmm5
    maxss    %xmm3, %xmm5
    mulss    .LCPI1_2(%rip), %xmm0

    addss    %xmm4, %xmm0

    addss    %xmm2, %xmm2
    addss    %xmm0, %xmm2
    mulss    .LCPI1_3(%rip), %xmm1
    addss    %xmm2, %xmm1
    divss    %xmm5, %xmm1
    movss    .LCPI1_4(%rip), %xmm0
    ucomiss    %xmm1, %xmm0
    ja    .LBB1_2

Unless i'm wrong, xmm4 is never used for the computation.
And with another test case (same computation however) we have no additional
register:
    movaps    %xmm0, %xmm3
    mulss    %xmm3, %xmm3

    movaps    %xmm2, %xmm4
    mulss    %xmm4, %xmm4
    addss    %xmm3, %xmm4
    movaps    %xmm1, %xmm3
    mulss    %xmm3, %xmm3
    addss    %xmm4, %xmm3
    sqrtss    %xmm3, %xmm3
    mulss    .LCPI2_0(%rip), %xmm3
    movss    .LCPI2_1(%rip), %xmm4
    maxss    %xmm3, %xmm4
    mulss    .LCPI2_2(%rip), %xmm0

    addss    %xmm2, %xmm2
    addss    %xmm0, %xmm2
    mulss    .LCPI2_3(%rip), %xmm1
    addss    %xmm2, %xmm1
    divss    %xmm4, %xmm1
    movss    .LCPI2_4(%rip), %xmm0
    ucomiss    %xmm1, %xmm0
    ja    .LBB2_2

The first function in CPP looks like this:
float Do(int ac)
{
    return Vec3(5, 2, -7).angleBetween(Vec3(ac, ac * 2, ac * -3)).count();
    // count() <==> static_cast<float>
}

template<typename Quantity, size_t Size>
class Vector
{
    explicit constexpr Vector(Arg&&... args) :
        m_values{Quantity(args)...}
    {
    }

    ...

    inline Angle angleBetween(const Vector& vec)
    {
        SquaredQuantity lenProduct = length() * vec.length();
    if (lenProduct < SquaredQuantity(1e-6f))
        lenProduct = SquaredQuantity(1e-6f);
    Constant rotation = Clamp(dotProduct(vec) / lenProduct, -1_c, 1_c);
    return Acos(rotation);
    }

    length(), dotProduct(), Clamp and Acos are also inline functions
    using fixed-size loops like:
    constexpr SquaredQuantity dotProduct(const Vector& vec) const
    {
    SquaredQuantity product(0.0);
    for (size_t i = 0; i < Size; ++i)
        product += m_values[i] * vec.at(i);
    return product;
    }

    ...
private:
    Quantity m_values[Size];
}

Quantity is a class template wrapping a float, only used for strict typing.
The other which is bug-free is the same computation the C way:

struct V3
{
    float tab[3];
};

float Do2(int ac)
{
    V3 vec{{5.0f, 2.0f, -7.0f}};
    V3 otherVec{{float(ac), float(ac * 2), float(ac * -3)}};
    float lenProduct = std::sqrt(vec.tab[0] * vec.tab[0] + vec.tab[1] *
vec.tab[1] + vec.tab[2] * vec.tab[2]) *
    std::sqrt(otherVec.tab[0] * otherVec.tab[0] + otherVec.tab[1] *
otherVec.tab[1] + otherVec.tab[2] * otherVec.tab[2]);
    if (lenProduct < 1e-6f)
        lenProduct = 1e-6f;
    float product = vec.tab[0] * otherVec.tab[0] + vec.tab[1] * otherVec.tab[1]
+ vec.tab[2] * otherVec.tab[2];
    float rotation = Clamp(product / lenProduct, -1.0f, 1.0f);
    return std::acos(rotation);
}



Here's the LLVM code with the bug:

; Function Attrs: nounwind readnone uwtable
define float @_Z2Doi(i32 %ac) #4 {
  %1 = shl nsw i32 %ac, 1
  %2 = mul nsw i32 %ac, -3
  %3 = sitofp i32 %ac to float
  %4 = sitofp i32 %1 to float
  %5 = sitofp i32 %2 to float

  %6 = fmul float %3, %3
  %7 = fadd float %6, 0.000000e+00    <- maybe here?

  %8 = fmul float %4, %4
  %9 = fadd float %7, %8

  %10 = fmul float %5, %5
  %11 = fadd float %10, %9

  %12 = tail call float @sqrtf(float %11) #8
  %13 = fmul float %12, 0x4021A9DC80000000
  %14 = fcmp olt float %13, 0x3EB0C6F7A0000000
  %15 = select i1 %14, float 0x3EB0C6F7A0000000, float %13
  %16 = fmul float %3, 5.000000e+00
  %17 = fadd float %16, 0.000000e+00
  %18 = fmul float %4, 2.000000e+00
  %19 = fadd float %17, %18
  %20 = fmul float %5, -7.000000e+00
  %21 = fadd float %20, %19
  %22 = fdiv float %21, %15
  %23 = fcmp olt float %22, -1.000000e+00
  br i1 %23, label
%_ZN6studio6VectorINS_8QuantityILi0ELi1ELi0EEELm3EE12angleBetweenERKS3_.exit,
label %24

; <label>:24                                      ; preds = %0
  %25 = fcmp ogt float %22, 1.000000e+00
  %.pre.i = select i1 %25, float 1.000000e+00, float %22
  br label
%_ZN6studio6VectorINS_8QuantityILi0ELi1ELi0EEELm3EE12angleBetweenERKS3_.exit

_ZN6studio6VectorINS_8QuantityILi0ELi1ELi0EEELm3EE12angleBetweenERKS3_.exit: ;
preds = %0, %24
  %26 = phi float [ -1.000000e+00, %0 ], [ %.pre.i, %24 ]
  %27 = tail call float @acosf(float %26) #8
  ret float %27
}



And the LLVM code without:

; Function Attrs: nounwind readnone uwtable
define float @_Z3Do2i(i32 %ac) #4 {
  %1 = sitofp i32 %ac to float
  %2 = shl nsw i32 %ac, 1
  %3 = sitofp i32 %2 to float
  %4 = mul nsw i32 %ac, -3
  %5 = sitofp i32 %4 to float

  %6 = fmul float %1, %1

  %7 = fmul float %3, %3
  %8 = fadd float %6, %7

  %9 = fmul float %5, %5
  %10 = fadd float %9, %8

  %11 = tail call float @sqrtf(float %10) #8
  %12 = fmul float %11, 0x4021A9DC80000000
  %13 = fcmp olt float %12, 0x3EB0C6F7A0000000
  %lenProduct.0 = select i1 %13, float 0x3EB0C6F7A0000000, float %12
  %14 = fmul float %1, 5.000000e+00
  %15 = fmul float %3, 2.000000e+00
  %16 = fadd float %14, %15
  %17 = fmul float %5, -7.000000e+00
  %18 = fadd float %17, %16
  %19 = fdiv float %18, %lenProduct.0
  %20 = fcmp olt float %19, -1.000000e+00
  br i1 %20, label %_ZN6studio5ClampIfEERKT_S3_S3_S3_.exit, label %21

; <label>:21                                      ; preds = %0
  %22 = fcmp ogt float %19, 1.000000e+00
  %23 = select i1 %22, float 1.000000e+00, float %19
  br label %_ZN6studio5ClampIfEERKT_S3_S3_S3_.exit

_ZN6studio5ClampIfEERKT_S3_S3_S3_.exit:           ; preds = %0, %21
  %24 = phi float [ -1.000000e+00, %0 ], [ %23, %21 ]
  %25 = tail call float @acosf(float %24) #8
  ret float %25
}

I'm not sure at all wether it comes from my code, the cpp templates or the
optimizations with inlined functions, or anything else.
But I'm guessing it's a bug since the register is never used, or it's just some
very minor issue due to unoptimized cpp code?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160502/7cfee813/attachment.html>


More information about the llvm-bugs mailing list