<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>