From patchwork Thu Nov 20 09:48:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenqiang Chen X-Patchwork-Id: 412614 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6689514010B for ; Thu, 20 Nov 2014 20:49:18 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=glYL57xKZUI2EF8X YNeQEQGeiusl9Vx7tarjg2eb/3Ula0k1mhC1C+dwIcQJx+4W0M+1T3VEuj9Jq9hM 8R83y1UKoid2KPUtKVTRRGPVUChRuUff1/ivNLojEsFOqAb7wmHFS8gd3tVs7iAY qrKqoNsmMIdm8aLUfX2EJwR1/iI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=n55izJ795MHHef5ptsH+Rj YpePg=; b=HCqxGZzCb+A4uHMvm3feigGqZXxz3LiQC1WmX2onyRPkJd0/jIky8z 2tPPfLbpODBGhzGbC0YcfyR5Nd1vHA+3rRcRj77lp5ya1/bSr9C3Lx9ZA/D3JpSD z5SqX1/az1PmgktPNeW6ThkG1CIi2wZuSem1FClvNp5cDEMiXYv/s= Received: (qmail 18397 invoked by alias); 20 Nov 2014 09:48:52 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 18323 invoked by uid 89); 20 Nov 2014 09:48:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: service87.mimecast.com Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Nov 2014 09:48:48 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Thu, 20 Nov 2014 09:48:45 +0000 Received: from shawin003 ([10.164.2.42]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 20 Nov 2014 09:48:42 +0000 From: "Zhenqiang Chen" To: Subject: [PATCH, ifcvt] Fix PR63917 Date: Thu, 20 Nov 2014 17:48:26 +0800 Message-ID: <000001d004a7$2248cbb0$66da6310$@arm.com> MIME-Version: 1.0 X-MC-Unique: 114112009484511001 X-IsSubscribed: yes Hi, r217646 enhances ifcvt to handle cbranchcc4 instruction. But ifcvt does not strictly check the dependence before moving instructions before IF. Then some instructions, which clobber CC, are inserted before the cbranchcc4 instruction. For the case in the patch, ifcvt transfers code from 5: r87:SI=r117:SI 22: pc={(flags:CCGOC>=0)?L26:pc} 25: {r87:SI=-r117:SI;clobber flags:CC;} to 5: r87:SI=r117:SI 136: {r145:SI=-r117:SI;clobber flags:CC;} // CC is clobbered 137: r87:SI={(flags:CCGOC<0)?r145:SI:r117:SI} The patch skips moving insns, which clobber CC, before cbranchcc4. Bootstrap and no make check regression on X86-64 and i686. All the failed cases in PR63917 PASS. OK for trunk? Thanks! -Zhenqiang ChangeLog: 2014-11-20 Zhenqiang Chen PR rtl-optimization/63917 * ifcvt.c (clobber_cc_p, use_cc_p): New functions. (noce_process_if_block, check_cond_move_block): Check CC references. testsuite/ChangeLog: 2014-11-20 Zhenqiang Chen * gcc.target/i386/floatsitf.c: New test. long)) (_FP_FROM_INT_lz) = __builtin_clzll ((unsigned int) _FP_FROM_INT_ur); else abort (); } while (0); A_e = (16383 + 32 - 1 - _FP_FROM_INT_lz); }) : (((((8 * (int) sizeof (SItype)))) <= 2 * 32) ? ({ int _FP_FROM_INT_lz; do { if ((unsigned int) (_FP_FROM_INT_ur >> 32)) do { if (sizeof (unsigned int) == sizeof (unsigned int)) ((_FP_FROM_INT_lz)) = __builtin_clz ((unsigned int) (_FP_FROM_INT_ur >> 32)); else if (sizeof (unsigned int) == sizeof (unsigned long)) ((_FP_FROM_INT_lz)) = __builtin_clzl ((unsigned int) (_FP_FROM_INT_ur >> 32)); else if (sizeof (unsigned int) == sizeof (unsigned long long)) ((_FP_FROM_INT_lz)) = __builtin_clzll ((unsigned int) (_FP_FROM_INT_ur >> 32)); else abort (); } while (0); else { do { if (sizeof (unsigned int) == sizeof (unsigned int)) ((_FP_FROM_INT_lz)) = __builtin_clz ((unsigned int) _FP_FROM_INT_ur); else if (sizeof (unsigned int) == sizeof (unsigned long)) ((_FP_FROM_INT_lz)) = __builtin_clzl ((unsigned int) _FP_FROM_INT_ur); else if (sizeof (unsigned int) == sizeof (unsigned long long)) ((_FP_FROM_INT_lz)) = __builtin_clzll ((unsigned int) _FP_FROM_INT_ur); else abort (); } while (0); (_FP_FROM_INT_lz) += 32; } } while (0); A_e = (16383 + 2 * 32 - 1 - _FP_FROM_INT_lz); }) : (abort (), 0))); if ((((8 * (int) sizeof (SItype)))) - 1 + 16383 >= 32767 && A_e >= 32767) { do { if (0xc00 == 0 || (0xc00 == 0x800 && !A_s) || (0xc00 == 0x400 && A_s)) { A_e = 32767; (A_f[3] = 0, A_f[2] = 0, A_f[1] = 0, A_f[0] = 0); } else { A_e = 32767 - 1; (A_f[3] = (~(signed int) 0), A_f[2] = (~(signed int) 0), A_f[1] = (~(signed int) 0), A_f[0] = (~(signed int) 0)); } do {} while (0); do {} while (0); } while (0); goto pack_semiraw; } if ((((8 * (int) sizeof (SItype)))) <= 113 || A_e < 16383 + 113) { do { A_f[0] = (_FP_FROM_INT_ur); A_f[1] = (((((8 * (int) sizeof (SItype))))) <= 32 ? 0 : (_FP_FROM_INT_ur) >> 32); A_f[2] = (((((8 * (int) sizeof (SItype))))) <= 2*32 ? 0 : (_FP_FROM_INT_ur) >> 2*32); A_f[3] = (((((8 * (int) sizeof (SItype))))) <= 3*32 ? 0 : (_FP_FROM_INT_ur) >> 3*32); } while (0); if (16383 + 113 - 1 - A_e > 0) do { int _FP_FRAC_SLL_4_up, _FP_FRAC_SLL_4_down; int _FP_FRAC_SLL_4_skip, _FP_FRAC_SLL_4_i; _FP_FRAC_SLL_4_skip = ((16383 + 113 - 1 - A_e)) / 32; _FP_FRAC_SLL_4_up = ((16383 + 113 - 1 - A_e)) % 32; _FP_FRAC_SLL_4_down = 32 - _FP_FRAC_SLL_4_up; if (!_FP_FRAC_SLL_4_up) for (_FP_FRAC_SLL_4_i = 3; _FP_FRAC_SLL_4_i >= _FP_FRAC_SLL_4_skip; --_FP_FRAC_SLL_4_i) A_f[_FP_FRAC_SLL_4_i] = A_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip]; else { for (_FP_FRAC_SLL_4_i = 3; _FP_FRAC_SLL_4_i > _FP_FRAC_SLL_4_skip; --_FP_FRAC_SLL_4_i) A_f[_FP_FRAC_SLL_4_i] = ((A_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip] << _FP_FRAC_SLL_4_up) | (A_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip-1] >> _FP_FRAC_SLL_4_down)); A_f[_FP_FRAC_SLL_4_i--] = A_f[0] << _FP_FRAC_SLL_4_up; } for (; _FP_FRAC_SLL_4_i >= 0; --_FP_FRAC_SLL_4_i) A_f[_FP_FRAC_SLL_4_i] = 0; } while (0); } else { if (16383 + (3 + 113) - 1 < A_e) _FP_FROM_INT_ur = ((_FP_FROM_INT_ur >> (A_e - 16383 - (3 + 113) + 1)) | ((_FP_FROM_INT_ur << ((((8 * (int) sizeof (SItype)))) - (A_e - 16383 - (3 + 113) + 1))) != 0)); do { A_f[0] = (_FP_FROM_INT_ur); A_f[1] = (((((8 * (int) sizeof (SItype))))) <= 32 ? 0 : (_FP_FROM_INT_ur) >> 32); A_f[2] = (((((8 * (int) sizeof (SItype))))) <= 2*32 ? 0 : (_FP_FROM_INT_ur) >> 2*32); A_f[3] = (((((8 * (int) sizeof (SItype))))) <= 3*32 ? 0 : (_FP_FROM_INT_ur) >> 3*32); } while (0); if ((16383 + (3 + 113) - 1 - A_e) > 0) do { int _FP_FRAC_SLL_4_up, _FP_FRAC_SLL_4_down; int _FP_FRAC_SLL_4_skip, _FP_FRAC_SLL_4_i; _FP_FRAC_SLL_4_skip = ((16383 + (3 + 113) - 1 - A_e)) / 32; _FP_FRAC_SLL_4_up = ((16383 + (3 + 113) - 1 - A_e)) % 32; _FP_FRAC_SLL_4_down = 32 - _FP_FRAC_SLL_4_up; if (!_FP_FRAC_SLL_4_up) for (_FP_FRAC_SLL_4_i = 3; _FP_FRAC_SLL_4_i >= _FP_FRAC_SLL_4_skip; --_FP_FRAC_SLL_4_i) A_f[_FP_FRAC_SLL_4_i] = A_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip]; else { for (_FP_FRAC_SLL_4_i = 3; _FP_FRAC_SLL_4_i > _FP_FRAC_SLL_4_skip; --_FP_FRAC_SLL_4_i) A_f[_FP_FRAC_SLL_4_i] = ((A_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip] << _FP_FRAC_SLL_4_up) | (A_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip-1] >> _FP_FRAC_SLL_4_down)); A_f[_FP_FRAC_SLL_4_i--] = A_f[0] << _FP_FRAC_SLL_4_up; } for (; _FP_FRAC_SLL_4_i >= 0; --_FP_FRAC_SLL_4_i) A_f[_FP_FRAC_SLL_4_i] = 0; } while (0); (A_f[3]) &= ~(unsigned int) ((unsigned int) 1 << (113 -1+3) % 32); pack_semiraw: do { int _FP_PACK_SEMIRAW_is_tiny = A_e == 0 && !((A_f[0] | A_f[1] | A_f[2] | A_f[3]) == 0); if (0 && _FP_PACK_SEMIRAW_is_tiny) { int _FP_PACK_SEMIRAW_T_c __attribute__ ((unused)); int _FP_PACK_SEMIRAW_T_s __attribute__ ((unused)); int _FP_PACK_SEMIRAW_T_e __attribute__ ((unused)); unsigned int _FP_PACK_SEMIRAW_T_f[4]; (_FP_PACK_SEMIRAW_T_f[0] = A_f[0], _FP_PACK_SEMIRAW_T_f[1] = A_f[1], _FP_PACK_SEMIRAW_T_f[2] = A_f[2], _FP_PACK_SEMIRAW_T_f[3] = A_f[3]); _FP_PACK_SEMIRAW_T_s = A_s; _FP_PACK_SEMIRAW_T_e = A_e; do { int _FP_FRAC_SLL_4_up, _FP_FRAC_SLL_4_down; int _FP_FRAC_SLL_4_skip, _FP_FRAC_SLL_4_i; _FP_FRAC_SLL_4_skip = (1) / 32; _FP_FRAC_SLL_4_up = (1) % 32; _FP_FRAC_SLL_4_down = 32 - _FP_FRAC_SLL_4_up; if (!_FP_FRAC_SLL_4_up) for (_FP_FRAC_SLL_4_i = 3; _FP_FRAC_SLL_4_i >= _FP_FRAC_SLL_4_skip; --_FP_FRAC_SLL_4_i) _FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i] = _FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip]; else { for (_FP_FRAC_SLL_4_i = 3; _FP_FRAC_SLL_4_i > _FP_FRAC_SLL_4_skip; --_FP_FRAC_SLL_4_i) _FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i] = ((_FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip] << _FP_FRAC_SLL_4_up) | (_FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip-1] >> _FP_FRAC_SLL_4_down)); _FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i--] = _FP_PACK_SEMIRAW_T_f[0] << _FP_FRAC_SLL_4_up; } for (; _FP_FRAC_SLL_4_i >= 0; --_FP_FRAC_SLL_4_i) _FP_PACK_SEMIRAW_T_f[_FP_FRAC_SLL_4_i] = 0; } while (0); do { if ((_FP_PACK_SEMIRAW_T_f[0]) & 7) { do {} while (0); switch (0xc00) { case 0: do { if (((_FP_PACK_SEMIRAW_T_f[0]) & 15) != ((unsigned int) 1 << 2)) __asm__ ("add{l} {%4,%3|%3,%4}\n\t" "adc{l} {$0,%2|%2,0}\n\t" "adc{l} {$0,%1|%1,0}\n\t" "adc{l} {$0,%0|%0,0}" : "+r" ((USItype) (_FP_PACK_SEMIRAW_T_f[3])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[2])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[1])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[0])) : "g" ((USItype) (((unsigned int) 1 << 2)))); } while (0); break; case 0xc00: (void) 0; break; case 0x800: do { if (!_FP_PACK_SEMIRAW_T_s && ((_FP_PACK_SEMIRAW_T_f[0]) & 7)) __asm__ ("add{l} {%4,%3|%3,%4}\n\t" "adc{l} {$0,%2|%2,0}\n\t" "adc{l} {$0,%1|%1,0}\n\t" "adc{l} {$0,%0|%0,0}" : "+r" ((USItype) (_FP_PACK_SEMIRAW_T_f[3])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[2])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[1])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[0])) : "g" ((USItype) (((unsigned int) 1 << 3)))); } while (0); break; case 0x400: do { if (_FP_PACK_SEMIRAW_T_s && ((_FP_PACK_SEMIRAW_T_f[0]) & 7)) __asm__ ("add{l} {%4,%3|%3,%4}\n\t" "adc{l} {$0,%2|%2,0}\n\t" "adc{l} {$0,%1|%1,0}\n\t" "adc{l} {$0,%0|%0,0}" : "+r" ((USItype) (_FP_PACK_SEMIRAW_T_f[3])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[2])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[1])), "+&r" ((USItype) (_FP_PACK_SEMIRAW_T_f[0])) : "g" ((USItype) (((unsigned int) 1 << 3)))); } while (0); break; } } } while (0); if (((_FP_PACK_SEMIRAW_T_f[3]) & ((unsigned int) 1 << ((3 + 113) % 32)))) _FP_PACK_SEMIRAW_is_tiny = 0; } do { if ((A_f[0]) & 7) { do {} while (0); switch (0xc00) { case 0: do { if (((A_f[0]) & 15) != ((unsigned int) 1 << 2)) __asm__ ("add{l} {%4,%3|%3,%4}\n\t" "adc{l} {$0,%2|%2,0}\n\t" "adc{l} {$0,%1|%1,0}\n\t" "adc{l} {$0,%0|%0,0}" : "+r" ((USItype) (A_f[3])), "+&r" ((USItype) (A_f[2])), "+&r" ((USItype) (A_f[1])), "+&r" ((USItype) (A_f[0])) : "g" ((USItype) (((unsigned int) 1 << 2)))); } while (0); break; case 0xc00: (void) 0; break; case 0x800: do { if (!A_s && ((A_f[0]) & 7)) __asm__ ("add{l} {%4,%3|%3,%4}\n\t" "adc{l} {$0,%2|%2,0}\n\t" "adc{l} {$0,%1|%1,0}\n\t" "adc{l} {$0,%0|%0,0}" : "+r" ((USItype) (A_f[3])), "+&r" ((USItype) (A_f[2])), "+&r" ((USItype) (A_f[1])), "+&r" ((USItype) (A_f[0])) : "g" ((USItype) (((unsigned int) 1 << 3)))); } while (0); break; case 0x400: do { if (A_s && ((A_f[0]) & 7)) __asm__ ("add{l} {%4,%3|%3,%4}\n\t" "adc{l} {$0,%2|%2,0}\n\t" "adc{l} {$0,%1|%1,0}\n\t" "adc{l} {$0,%0|%0,0}" : "+r" ((USItype) (A_f[3])), "+&r" ((USItype) (A_f[2])), "+&r" ((USItype) (A_f[1])), "+&r" ((USItype) (A_f[0])) : "g" ((USItype) (((unsigned int) 1 << 3)))); } while (0); break; } } } while (0); if (_FP_PACK_SEMIRAW_is_tiny) { if ((0 & 0x20) || (0 & 0x10)) do {} while (0); } if ((A_f[3]) & (((unsigned int) 1 << ((3 + 113) % 32)) >> 1)) { (A_f[3]) &= ~(((unsigned int) 1 << ((3 + 113) % 32)) >> 1); A_e++; if (A_e == 32767) do { if (0xc00 == 0 || (0xc00 == 0x800 && !A_s) || (0xc00 == 0x400 && A_s)) { A_e = 32767; (A_f[3] = 0, A_f[2] = 0, A_f[1] = 0, A_f[0] = 0); } else { A_e = 32767 - 1; (A_f[3] = (~(signed int) 0), A_f[2] = (~(signed int) 0), A_f[1] = (~(signed int) 0), A_f[0] = (~(signed int) 0)); } do {} while (0); do {} while (0); } while (0); } do { int _FP_FRAC_SRL_4_up, _FP_FRAC_SRL_4_down; int _FP_FRAC_SRL_4_skip, _FP_FRAC_SRL_4_i; _FP_FRAC_SRL_4_skip = (3) / 32; _FP_FRAC_SRL_4_down = (3) % 32; _FP_FRAC_SRL_4_up = 32 - _FP_FRAC_SRL_4_down; if (!_FP_FRAC_SRL_4_down) for (_FP_FRAC_SRL_4_i = 0; _FP_FRAC_SRL_4_i <= 3-_FP_FRAC_SRL_4_skip; ++_FP_FRAC_SRL_4_i) A_f[_FP_FRAC_SRL_4_i] = A_f[_FP_FRAC_SRL_4_i+_FP_FRAC_SRL_4_skip]; else { for (_FP_FRAC_SRL_4_i = 0; _FP_FRAC_SRL_4_i < 3-_FP_FRAC_SRL_4_skip; ++_FP_FRAC_SRL_4_i) A_f[_FP_FRAC_SRL_4_i] = ((A_f[_FP_FRAC_SRL_4_i+_FP_FRAC_SRL_4_skip] >> _FP_FRAC_SRL_4_down) | (A_f[_FP_FRAC_SRL_4_i+_FP_FRAC_SRL_4_skip+1] << _FP_FRAC_SRL_4_up)); A_f[_FP_FRAC_SRL_4_i++] = A_f[3] >> _FP_FRAC_SRL_4_down; } for (; _FP_FRAC_SRL_4_i < 4; ++_FP_FRAC_SRL_4_i) A_f[_FP_FRAC_SRL_4_i] = 0; } while (0); if (A_e == 32767 && !((A_f[0] | A_f[1] | A_f[2] | A_f[3]) == 0)) { if (!1) { (A_f[3] = ((unsigned int) 1 << (113 -2) % 32), A_f[2] = 0, A_f[1] = 0, A_f[0] = 0); A_s = 1; } else do { if (0) { (A_f[3]) &= ((unsigned int) 1 << (113 -2) % 32) - 1; if (((A_f[0] | A_f[1] | A_f[2] | A_f[3]) == 0)) { A_s = 1; (A_f[3] = ((unsigned int) 1 << (113 -2) % 32), A_f[2] = 0, A_f[1] = 0, A_f[0] = 0); } } else (A_f[3]) |= ((unsigned int) 1 << (113 -2) % 32); } while (0); } } while (0); } } else { A_s = 0; A_e = 0; (A_f[3] = 0, A_f[2] = 0, A_f[1] = 0, A_f[0] = 0); } } while (0); + do { union _FP_UNION_Q _FP_PACK_RAW_4_flo; _FP_PACK_RAW_4_flo.bits.frac0 = A_f[0]; _FP_PACK_RAW_4_flo.bits.frac1 = A_f[1]; _FP_PACK_RAW_4_flo.bits.frac2 = A_f[2]; _FP_PACK_RAW_4_flo.bits.frac3 = A_f[3]; _FP_PACK_RAW_4_flo.bits.exp = A_e; _FP_PACK_RAW_4_flo.bits.sign = A_s; ((a)) = _FP_PACK_RAW_4_flo.flt; } while (0); + + return a; +} + +/* { dg-final { scan-rtl-dump "0 IF blocks converted" "ce2" } } */ +/* { dg-final { cleanup-rtl-dump "ce2" } } */ diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 21f08c2..760eeb6 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -2528,6 +2528,34 @@ noce_can_store_speculate_p (basic_block top_bb, const_rtx mem) return false; } +/* Check X clobber CC reg or not. */ + +static bool +clobber_cc_p (rtx x) +{ + RTX_CODE code = GET_CODE (x); + int i; + + if (code == CLOBBER + && REG_P (XEXP (x, 0)) + && (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_CC)) + return TRUE; + else if (code == PARALLEL) + for (i = 0; i < XVECLEN (x, 0); i++) + if (clobber_cc_p (XVECEXP (x, 0, i))) + return TRUE; + return FALSE; +} + +/* Check CC reg is used in COND or not. */ + +static bool +use_cc_p (rtx cond) +{ + return (HAVE_cbranchcc4) + && (GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC); +} + /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert it without using conditional execution. Return TRUE if we were successful at converting the block. */ @@ -2655,6 +2683,12 @@ noce_process_if_block (struct noce_if_info *if_info) if_info->a = a; if_info->b = b; + /* Skip it if the instruction to be moved might clobber CC. */ + if (use_cc_p (if_info->cond) + && (clobber_cc_p (PATTERN (insn_a)) + || (insn_b && clobber_cc_p (PATTERN (insn_b))))) + return FALSE; + /* Try optimizations in some approximation of a useful order. */ /* ??? Should first look to see if X is live incoming at all. If it isn't, we don't need anything but an unconditional set. */ @@ -2868,6 +2902,10 @@ check_cond_move_block (basic_block bb, && modified_between_p (src, insn, NEXT_INSN (BB_END (bb)))) return FALSE; + /* Skip it if the instruction to be moved might clobber CC. */ + if (use_cc_p (cond) && clobber_cc_p (PATTERN (insn))) + return FALSE; + vals->put (dest, src); regs->safe_push (dest); diff --git a/gcc/testsuite/gcc.target/i386/floatsitf.c b/gcc/testsuite/gcc.target/i386/floatsitf.c new file mode 100644 index 0000000..6b249cc --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/floatsitf.c @@ -0,0 +1,48 @@ +/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +/* { dg-options "-O2 -fdump-rtl-ce2" } */ + +typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); +void __sfp_handle_exceptions (int); + +typedef int QItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +typedef unsigned int UHWtype __attribute__ ((mode (HI))); +extern const UQItype __clz_tab[256] ; + +extern void abort (void); +typedef float TFtype __attribute__ ((mode (TF))); + +union _FP_UNION_Q +{ + TFtype flt; + struct + { + unsigned long frac0 : 32; + unsigned long frac1 : 32; + unsigned long frac2 : 32; + unsigned long frac3 : 113 - (((unsigned int) 1 << (113 -1) % 32) != 0)-(32 * 3); + unsigned exp : 15; + unsigned sign : 1; + + } bits __attribute__ ((packed)); +}; + +TFtype +__floatsitf (SItype i) +{ + int A_c __attribute__ ((unused)); int A_s __attribute__ ((unused)); int A_e __attribute__ ((unused)); unsigned int A_f[4]; + TFtype a; + + do { if ((i)) { USItype _FP_FROM_INT_ur; if ((A_s = (((i)) < 0))) ((i)) = -(USItype) ((i)); _FP_FROM_INT_ur = (USItype) ((i)); (void) (((((8 * (int) sizeof (SItype)))) <= 32) ? ({ int _FP_FROM_INT_lz; do { if (sizeof (unsigned int) == sizeof (unsigned int)) (_FP_FROM_INT_lz) = __builtin_clz ((unsigned int) _FP_FROM_INT_ur); else if (sizeof (unsigned int) == sizeof (unsigned long)) (_FP_FROM_INT_lz) = __builtin_clzl ((unsigned int) _FP_FROM_INT_ur); else if (sizeof (unsigned int) == sizeof (unsigned long