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: unassignedb...@nondot.org Reporter: car...@google.com CC: llvm-bugs@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.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs