[llvm-bugs] [Bug 30483] New: [ppc] too many cr manipulation instructions are used for comparisons

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Sep 21 16:50:24 PDT 2016


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

            Bug ID: 30483
           Summary: [ppc] too many cr manipulation instructions are used
                    for comparisons
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: PowerPC
          Assignee: unassignedbugs at nondot.org
          Reporter: carrot at google.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

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.

-- 
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/20160921/64850f30/attachment.html>


More information about the llvm-bugs mailing list