<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 --- - [ppc] too many cr manipulation instructions are used for comparisons"
href="https://llvm.org/bugs/show_bug.cgi?id=30483">30483</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[ppc] too many cr manipulation instructions are used for comparisons
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</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>Backend: PowerPC
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>carrot@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>The source code is simplified from a protocol buffer test case,
class PB1{
public:
bool has_f1() const;
int f1() const;
bool has_f2() const;
unsigned long long f2() const;
bool has_f3() const;
unsigned long long f3() const;
unsigned int _has_bits_[1];
unsigned long long f2_;
unsigned long long f3_;
int f1_;
};
class PB2{
public:
bool has_pb1() const;
const PB1& pb1() const;
unsigned int _has_bits_[1];
PB1* pb1_;
};
inline bool PB1::has_f1() const {
return (_has_bits_[0] & 0x00000004u) != 0;
}
inline int PB1::f1() const {
return f1_;
}
inline bool PB1::has_f2() const {
return (_has_bits_[0] & 0x00000008u) != 0;
}
inline unsigned long long PB1::f2() const {
return f2_;
}
inline bool PB1::has_f3() const {
return (_has_bits_[0] & 0x00000010u) != 0;
}
inline unsigned long long PB1::f3() const {
return f3_;
}
inline bool PB2::has_pb1() const {
return (_has_bits_[0] & 0x00000008u) != 0;
}
inline const PB1& PB2::pb1() const {
return *pb1_;
}
bool foo(const PB2& s_a, const PB2& s_b) {
if (s_a.has_pb1() != s_b.has_pb1()) {
return s_a.has_pb1() < s_b.has_pb1();
}
if (s_a.has_pb1()) {
const PB1& v_a = s_a.pb1();
const PB1& v_b = s_b.pb1();
if (v_a.has_f2() != v_b.has_f2()) { return v_a.has_f2() < v_b.has_f2(); }
if (v_a.has_f2() && (v_a.f2() != v_b.f2())) { return v_a.f2() < v_b.f2(); }
if (v_a.has_f3() != v_b.has_f3()) { return v_a.has_f3() < v_b.has_f3(); }
if (v_a.has_f3() && (v_a.f3() != v_b.f3())) { return v_a.f3() < v_b.f3(); }
if (v_a.has_f1() != v_b.has_f1()) { return v_a.has_f1() < v_b.has_f1(); }
if (v_a.has_f1() && (v_a.f1() != v_b.f1())) { return v_a.f1() < v_b.f1(); }
}
return false;
}
The function foo contains many comparisons, when compiled with options
-m64 -O2 -mvsx -mcpu=power8
LLVM generates code with many slow cr manipulation instructions, following is
first part of them:
_Z3fooRK3PB2S1_: # @_Z3fooRK3PB2S1_
.Lfunc_begin0:
# BB#0: # %entry
lbz 5, 0(3)
lbz 6, 0(4)
srwi 7, 5, 3
xor 5, 5, 6
srwi 6, 6, 3
andi. 7, 7, 1
srwi 5, 5, 3
crmove 20, 1
andi. 6, 6, 1
crmove 21, 1
andi. 5, 5, 1
bc 4, 1, .LBB0_2
# BB#1: # %if.then
crandc 22, 21, 20
b .LBB0_14
.LBB0_2: # %if.end
crxor 22, 22, 22
bc 4, 20, .LBB0_14
# BB#3: # %if.then9
ld 3, 8(3)
ld 4, 8(4)
lwz 6, 0(3)
lwz 5, 0(4)
rlwinm 8, 6, 29, 31, 31
rlwinm 7, 6, 0, 28, 28
andi. 8, 8, 1
xor 7, 7, 5
srwi 8, 5, 3
srwi 7, 7, 3
crmove 20, 1
andi. 8, 8, 1
crmove 21, 1
andi. 7, 7, 1
bc 4, 1, .LBB0_5
# BB#4: # %if.then17
crandc 22, 21, 20
b .LBB0_14
...
It causes 40% slower than gcc.
It should be handled by PPCBoolRetToInt.cpp.</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>