From patchwork Mon Sep 26 13:19:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pitchumani Sivanupandi X-Patchwork-Id: 675158 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 3sjPjH6vY1z9s5g for ; Mon, 26 Sep 2016 23:20:35 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=JnRIAvfA; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:cc:message-id:date:mime-version:content-type; q=dns; s=default; b=qfoR7GJFhQZNQ5OcmpIGCQ4POroK+mAMB9H/hGYnkC7IeicVzD 05794bVyIb9lUGivZZjh97gDMeeHfmfhcW4pWsPkCRqiSmKLiJ+/hy34utfuhr8X SjRhknqHecvYIBSO2tHi4sGJNijc1zgBYJm7EEln31FAdzfkV5FqtQokw= 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 :subject:to:cc:message-id:date:mime-version:content-type; s= default; bh=OPflGKp87KaDGEOe5nEy2M0toWM=; b=JnRIAvfASk2f4MBWghd4 UJEO8zTgnc/Gnxc+A6h8MBUuNbxBi9/zLRWQXzmtvWAh57v48vhS9uKQBPzBt2US RJ3luX1dOxIxAGK4fFudbBA2gxi8Xz3h9n31tal7q2g7LSz0EYJRe+UlyVN/sP25 8i5D8l4mTLM+HxYO+XxSkoo= Received: (qmail 123846 invoked by alias); 26 Sep 2016 13:20:27 -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 123825 invoked by uid 89); 26 Sep 2016 13:20:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=Hx-spam-relays-external:sk:smtpout, H*RU:sk:smtpout, Issues, H*r:sk:email.m X-HELO: email.microchip.com Received: from smtpout.microchip.com (HELO email.microchip.com) (198.175.253.82) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 26 Sep 2016 13:20:15 +0000 Received: from [10.40.233.140] (10.10.76.4) by chn-sv-exch05.mchp-main.com (10.10.76.106) with Microsoft SMTP Server id 14.3.181.6; Mon, 26 Sep 2016 06:20:10 -0700 From: Pitchumani Sivanupandi Subject: [patch, avr, pr71676 and pr71678] Issues with casesi expand To: GCC Patches CC: Denis Chertykov Message-ID: Date: Mon, 26 Sep 2016 18:49:52 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 Attached patch for PR71676 and PR71678. PR71676 is for AVR target that generates wrong code when switch case index is more than 16 bits. Switch case index of larger than SImode are checked for out of range before 'casesi' expand. RTL expand of casesi gets index as SImode, but index is compared in HImode and ignores upper 16bits. Attached patch changes the expansion for casesi to make the index comparison in SImode and code generation accordingly. PR71678 is ICE because below pattern in 'casesi' is not recognized. (set (reg:HI 47) (minus:HI (subreg:HI (subreg:SI (reg:DI 44) 0) 0) (reg:HI 45))) Fix of PR71676 avoids the above pattern as it changes the comparison to SImode. Regtested using avrtest. No regression found. If OK, could someone commit please? Is this OK for gcc-5-branch? Regards, Pitchumani gcc/ChangeLog 2016-09-26 Pitchumani Sivanupandi PR target/71676 PR target/71678 * config/avr/avr.md (casesi): Change index compare to SI mode. gcc/testsuite/ChangeLog 2016-09-26 Pitchumani Sivanupandi PR target/71676 PR target/71678 * gcc.target/avr/pr71676-1.c: New test. * gcc.target/avr/pr71676.c: New test. * gcc.target/avr/pr71678.c: New test. diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 97f3561..4b1bf9c 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -5155,12 +5155,12 @@ (define_expand "casesi" [(parallel [(set (match_dup 6) - (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0) - (match_operand:HI 1 "register_operand" ""))) + (minus:SI (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" ""))) (clobber (scratch:QI))]) (parallel [(set (cc0) (compare (match_dup 6) - (match_operand:HI 2 "register_operand" ""))) + (match_operand:SI 2 "register_operand" ""))) (clobber (match_scratch:QI 9 ""))]) (set (pc) @@ -5179,20 +5179,20 @@ (clobber (match_dup 8))])] "" { - operands[6] = gen_reg_rtx (HImode); + operands[6] = gen_reg_rtx (SImode); if (AVR_HAVE_EIJMP_EICALL) { - operands[7] = operands[6]; + operands[7] = simplify_gen_subreg (HImode, operands[6], SImode, 0); operands[8] = all_regs_rtx[24]; operands[10] = gen_rtx_REG (HImode, REG_Z); } else { - operands[7] = gen_rtx_PLUS (HImode, operands[6], + operands[7] = gen_rtx_PLUS (HImode, simplify_gen_subreg (HImode, operands[6], SImode, 0), gen_rtx_LABEL_REF (VOIDmode, operands[3])); operands[8] = const0_rtx; - operands[10] = operands[6]; + operands[10] = simplify_gen_subreg (HImode, operands[6], SImode, 0); } }) diff --git a/gcc/testsuite/gcc.target/avr/pr71676-1.c b/gcc/testsuite/gcc.target/avr/pr71676-1.c new file mode 100644 index 0000000..9a74909 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71676-1.c @@ -0,0 +1,332 @@ +/* { dg-do run } */ +/* { dg-options "-Os -Wno-overflow" } */ + +#include "exit-abort.h" +volatile unsigned char y; + +unsigned char __attribute__((noinline)) foo1 (char x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo2 (char x) +{ + switch (x) + { + case 0x01: y = 7; break; + case 0x02: y = 4; break; + case 0x03: y = 8; break; + case 0x04: y = 21; break; + case 0x05: y = 65; break; + case 0x06: y = 27; break; + case 0x07: y = 72; break; + case 0x08: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo3 (char x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo4 (char x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo5 (int x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo6 (int x) +{ + switch (x) + { + case 0x101: y = 7; break; + case 0x102: y = 4; break; + case 0x103: y = 8; break; + case 0x104: y = 21; break; + case 0x105: y = 65; break; + case 0x106: y = 27; break; + case 0x107: y = 72; break; + case 0x108: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo7 (int x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo8 (int x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo9 (long x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo10 (unsigned long x) +{ + switch (x) + { + case 0x100: y = 39; break; + case 0x101: y = 7; break; + case 0x102: y = 4; break; + case 0x103: y = 8; break; + case 0x104: y = 21; break; + case 0x105: y = 65; break; + case 0x106: y = 27; break; + case 0x107: y = 72; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo11 (long x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo12 (long x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo13 (long long x) +{ + switch (x) + { + case (char)0x11: y = 7; break; + case (char)0x12: y = 4; break; + case (char)0x13: y = 8; break; + case (char)0x14: y = 21; break; + case (char)0x15: y = 65; break; + case (char)0x16: y = 27; break; + case (char)0x17: y = 72; break; + case (char)0x18: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo14 (long long x) +{ + switch (x) + { + case 0x101: y = 7; break; + case 0x102: y = 4; break; + case 0x103: y = 8; break; + case 0x104: y = 21; break; + case 0x105: y = 65; break; + case 0x106: y = 27; break; + case 0x107: y = 72; break; + case 0x108: y = 39; break; + default: y=0; + } + return y; +} + +unsigned char __attribute__((noinline)) foo15 (long long x) +{ + switch (x) + { + case 0x1000001L: y = 7; break; + case 0x1000002L: y = 4; break; + case 0x1000003L: y = 8; break; + case 0x1000004L: y = 21; break; + case 0x1000005L: y = 65; break; + case 0x1000006L: y = 27; break; + case 0x1000007L: y = 72; break; + case 0x1000008L: y = 39; break; + default: y=0; + } + return y; +} + + +unsigned char __attribute__((noinline)) foo16 (long long x) +{ + switch (x) + { + case 0x100000001LL: y = 7; break; + case 0x100000002LL: y = 4; break; + case 0x100000003LL: y = 8; break; + case 0x100000004LL: y = 21; break; + case 0x100000005LL: y = 65; break; + case 0x100000006LL: y = 27; break; + case 0x100000007LL: y = 72; break; + case 0x100000008LL: y = 39; break; + default: y=0; + } + return y; +} + +int main () +{ + if (foo1 (0x13) != 8) + abort(); + + if (foo2 (0x06) != 27) + abort(); + + if (foo3 (0x02) != 4) + abort(); + + if (foo4 (0x01) != 7) + abort(); + + if (foo5 (0x15) != 65) + abort(); + + if (foo6 (0x103) != 8) + abort(); + + if (foo7 (0x04) != 21) + abort(); + + if (foo8 (0x07) != 72) + abort(); + + if (foo9 (0x10000011L) != 0) + abort(); + + if (foo10 (0x1000105L) != 0) + abort(); + + if (foo11 (0x1000008L) != 39) + abort(); + + if (foo12 (0x1000004L) != 0) + abort(); + + if (foo13 (0x109LL) != 0) + abort(); + + if (foo14 (0x108LL) != 39) + abort(); + + if (foo15 (0x1000001LL) != 7) + abort(); + + if (foo16 (0x100000004LL) != 21) + abort(); + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/avr/pr71676.c b/gcc/testsuite/gcc.target/avr/pr71676.c new file mode 100644 index 0000000..d7a543a --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71676.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-Os" } */ + +#include "exit-abort.h" + +volatile unsigned char y; + +__attribute__((noinline,noclone)) +unsigned char foo (unsigned long x) +{ + switch (x) + { + case 0: y = 67; break; + case 1: y = 20; break; + case 2: y = 109; break; + case 3: y = 33; break; + case 4: y = 44; break; + case 5: y = 37; break; + case 6: y = 10; break; + case 7: y = 98; break; + } + return y; +} + +int main (void) +{ + if (0 != foo (7L + 0x10000L)) + abort(); + return 0; +} + diff --git a/gcc/testsuite/gcc.target/avr/pr71678.c b/gcc/testsuite/gcc.target/avr/pr71678.c new file mode 100644 index 0000000..290d6cc --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr71678.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fno-tree-switch-conversion" } */ + +unsigned char foo (long long x) +{ + unsigned char y = 0; + switch (x) + { + case 0: y = 67; break; + case 1: y = 20; break; + case 2: y = 109; break; + case 3: y = 33; break; + case 4: y = 44; break; + case 5: y = 37; break; + case 6: y = 10; break; + case 7: y = 11; break; + } + return y; +} +