<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW " title="NEW --- - Clang emit wrong mangling of long double type for PPC64 in the Red Hat" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D23791&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=G2ssCMTXNa64DjgmOkiD14ClyIK4HxGQbqg-nSnq5QE&s=rMQyGIyN0f-qP3pn6JtRQeAN04NPfVM-2tBaPkT3IGw&e=">23791</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Clang emit wrong mangling of long double type for PPC64 in the Red Hat
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Other
</td>
</tr>
<tr>
<th>OS</th>
<td>other
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Frontend
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>bluechristlove@163.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>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'.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>