[LLVMbugs] [Bug 23791] New: Clang emit wrong mangling of long double type for PPC64 in the Red Hat

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Jun 9 02:15:26 PDT 2015


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

            Bug ID: 23791
           Summary: Clang emit wrong mangling of long double type for
                    PPC64 in the Red Hat
           Product: clang
           Version: trunk
          Hardware: Other
                OS: other
            Status: NEW
          Severity: normal
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: bluechristlove at 163.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

In the PPC64 architecture, Clang recognize the long double type and set the
long double format type as llvm::APFloat::PPCDoubleDouble which is in
PPCTargetInfo constructor of the file lib/Basic/Targets.cpp. The detail is like
this:

[code]

PPCTargetInfo(const llvm::Triple &Triple)
    : TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
      HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false),
      HasBPERMD(false), HasExtDiv(false) {
    BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
    LongDoubleWidth = LongDoubleAlign = 128;
    LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
  }

[/code]

and then in the function  getTypeForFormat of file
lib/codegen/CodeGenTypes.cpp, which return the type of PPC_FP128Ty, the code is
like this:
[code]

if (&format == &llvm::APFloat::PPCDoubleDouble)
    return llvm::Type::getPPC_FP128Ty(VMContext);

[/code]
// file: a.cpp
Let me show one simple example:
[code]

void foo(long double){}
int main(){}

[/code]

Compile command:

clang++ a.cpp -S -emit-llvm

Then view a.ll
...

; Function Attrs: nounwind
define void @_Z3foog(ppc_fp128) #0 {
entry:
  %.addr = alloca ppc_fp128, align 16
  store ppc_fp128 %0, ppc_fp128* %.addr, align 16
  ret void
}

...

we can find ppc_fp128, but let us view the object file of a.cpp.

clang++ -c a.cpp
readelf -Ws a.o

   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.cpp
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     7: 0000000000000000    24 FUNC    GLOBAL DEFAULT    1 _Z3fooe
     8: 0000000000000018    20 FUNC    GLOBAL DEFAULT    1 main

we can find that ppc_fp128 is encoded as 'e', which is in the function
CXXNameMangler::mangleType of the file lib/ast/ItaniumMangle.cpp, the code is:

[code]

case BuiltinType::LongDouble: Out << 'e'; break;

[/code]

But in the PPC64,this should be 'g'. 

Let us compile this code using gcc

g++ -c a.cpp
readelf -Ws a.o

 Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.cpp
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     9: 0000000000000000    44 FUNC    GLOBAL DEFAULT    1 _Z3foog
    10: 000000000000002c    44 FUNC    GLOBAL DEFAULT    1 main

We can find that the mangling name is _Z3foog, not _Z3fooe.

Because of this issue, which make some case can not pass.

[code]

#include <locale>
#include <sstream>
#include <string>
#include <iosfwd>
#include <sstream>
#include <iostream>

typedef std::char_traits<char> It_;
typedef std::ostreambuf_iterator<char, It_> Osit_;

struct Mymon_ : public std::money_put<char, Osit_>
{

    Mymon_(std::size_t refs)
    : std::money_put<char, Osit_>(refs)
    {
    }
};

struct Myimon_ : public std::money_put<char, Osit_>
{

    Myimon_(std:: size_t refs)
    : std::money_put<char, Osit_>(refs)
    {
    }
};

int main()
{
    Mymon_ fac(1), fac2(0);
}


[/code]

If we use clang++ to compile, which will report a linker error:\

a.o:(.data.rel.ro._ZTV6Mymon_[_ZTV6Mymon_]+0x30): undefined reference to
`std::__gnu_cxx_ldbl128::money_put<char, std::ostreambuf_iterator<char,
std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char,
std::char_traits<char> >, bool, std::ios_base&, char, long double) const'
clang: error: linker command failed with exit code 1 (use -v to see
invocation)\

If we readelf -Ws a.o

we can find this entry:

37: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basece

But gcc is like this:

46: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND
_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecg

Then we grep this in the libstdc++.so of a.o which produced by gcc:

readelf -Ws /usr/lib64/libstdc++.so.6 | grep
_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecg


 2948: 000000000016cbf8   756 FUNC    WEAK   DEFAULT   25
_ZNKSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES4_bRSt8ios_basecg@@GLIBCXX_LDBL_3.4

This can be found in the libstdc++

But this can not be found by the a.o which produced by clang, because Clang
emit wrong name mangling of long double in the PPC64 mentioned above.

So, in the CXXNameMangler::mangleType of the file lib/ast/ItaniumMangle.cpp,
when the case is case BuiltinType::LongDouble, Clang should detect the Target.
If the target is PPC64, which should be emit 'g', not 'e'.

-- 
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/20150609/10b4d957/attachment.html>


More information about the llvm-bugs mailing list