From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24901 invoked by alias); 2 Sep 2011 15:01:57 -0000 Received: (qmail 24886 invoked by uid 22791); 2 Sep 2011 15:01:54 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-wy0-f175.google.com (HELO mail-wy0-f175.google.com) (74.125.82.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 02 Sep 2011 15:01:40 +0000 Received: by wyf19 with SMTP id 19so2606874wyf.20 for ; Fri, 02 Sep 2011 08:01:38 -0700 (PDT) Received: by 10.227.19.194 with SMTP id c2mr1139111wbb.65.1314975698545; Fri, 02 Sep 2011 08:01:38 -0700 (PDT) Received: from richards-thinkpad.stglab.manchester.uk.ibm.com (gbibp9ph1--blueice2n1.emea.ibm.com [195.212.29.75]) by mx.google.com with ESMTPS id y12sm1959520wbo.25.2011.09.02.08.01.37 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 02 Sep 2011 08:01:38 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [ARM] PR target/49030: ICE in get_arm_condition_code Date: Fri, 02 Sep 2011 15:01:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-09/txt/msg00172.txt.bz2 CC_NCV rightly only allows GE(U) and LT(U). GT(U) and LE(U) have to implemented by reversing the condition. This is handled correctly when the condition is first expanded, but nothing stops later optimisers from producing invalid forms. This patch makes arm_comparison_operator check that the condition is acceptable. Tested on arm-linux-gnueabi. OK to install? Richard gcc/ * config/arm/arm-protos.h (maybe_get_arm_condition_code): Declare. * config/arm/arm.c (maybe_get_arm_condition_code): New function, reusing the old code from get_arm_condition_code. Return ARM_NV for invalid comparison codes. (get_arm_condition_code): Redefine in terms of maybe_get_arm_condition_code. * config/arm/predicates.md (arm_comparison_operator): Use maybe_get_arm_condition_code. gcc/testsuite/ * gcc.dg/torture/pr49030.c: New test. Index: gcc/config/arm/arm-protos.h =================================================================== --- gcc/config/arm/arm-protos.h 2011-09-02 15:46:44.013865635 +0100 +++ gcc/config/arm/arm-protos.h 2011-09-02 15:56:35.749477269 +0100 @@ -184,6 +184,7 @@ extern int is_called_in_ARM_mode (tree); #endif extern int thumb_shiftable_const (unsigned HOST_WIDE_INT); #ifdef RTX_CODE +extern enum arm_cond_code maybe_get_arm_condition_code (rtx); extern void thumb1_final_prescan_insn (rtx); extern void thumb2_final_prescan_insn (rtx); extern const char *thumb_load_double_from_address (rtx *); Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2011-09-02 15:46:44.013865635 +0100 +++ gcc/config/arm/arm.c 2011-09-02 15:56:35.756477252 +0100 @@ -17595,10 +17595,10 @@ arm_elf_asm_destructor (rtx symbol, int decremented/zeroed by arm_asm_output_opcode as the insns are output. */ /* Returns the index of the ARM condition code string in - `arm_condition_codes'. COMPARISON should be an rtx like - `(eq (...) (...))'. */ -static enum arm_cond_code -get_arm_condition_code (rtx comparison) + `arm_condition_codes', or ARM_NV if the comparison is invalid. + COMPARISON should be an rtx like `(eq (...) (...))'. */ +enum arm_cond_code +maybe_get_arm_condition_code (rtx comparison) { enum machine_mode mode = GET_MODE (XEXP (comparison, 0)); enum arm_cond_code code; @@ -17622,11 +17622,11 @@ get_arm_condition_code (rtx comparison) case CC_DLTUmode: code = ARM_CC; dominance: - gcc_assert (comp_code == EQ || comp_code == NE); - if (comp_code == EQ) return ARM_INVERSE_CONDITION_CODE (code); - return code; + if (comp_code == NE) + return code; + return ARM_NV; case CC_NOOVmode: switch (comp_code) @@ -17635,7 +17635,7 @@ get_arm_condition_code (rtx comparison) case EQ: return ARM_EQ; case GE: return ARM_PL; case LT: return ARM_MI; - default: gcc_unreachable (); + default: return ARM_NV; } case CC_Zmode: @@ -17643,7 +17643,7 @@ get_arm_condition_code (rtx comparison) { case NE: return ARM_NE; case EQ: return ARM_EQ; - default: gcc_unreachable (); + default: return ARM_NV; } case CC_Nmode: @@ -17651,7 +17651,7 @@ get_arm_condition_code (rtx comparison) { case NE: return ARM_MI; case EQ: return ARM_PL; - default: gcc_unreachable (); + default: return ARM_NV; } case CCFPEmode: @@ -17676,7 +17676,7 @@ get_arm_condition_code (rtx comparison) /* UNEQ and LTGT do not have a representation. */ case UNEQ: /* Fall through. */ case LTGT: /* Fall through. */ - default: gcc_unreachable (); + default: return ARM_NV; } case CC_SWPmode: @@ -17692,7 +17692,7 @@ get_arm_condition_code (rtx comparison) case GTU: return ARM_CC; case LEU: return ARM_CS; case LTU: return ARM_HI; - default: gcc_unreachable (); + default: return ARM_NV; } case CC_Cmode: @@ -17700,7 +17700,7 @@ get_arm_condition_code (rtx comparison) { case LTU: return ARM_CS; case GEU: return ARM_CC; - default: gcc_unreachable (); + default: return ARM_NV; } case CC_CZmode: @@ -17712,7 +17712,7 @@ get_arm_condition_code (rtx comparison) case GTU: return ARM_HI; case LEU: return ARM_LS; case LTU: return ARM_CC; - default: gcc_unreachable (); + default: return ARM_NV; } case CC_NCVmode: @@ -17722,7 +17722,7 @@ get_arm_condition_code (rtx comparison) case LT: return ARM_LT; case GEU: return ARM_CS; case LTU: return ARM_CC; - default: gcc_unreachable (); + default: return ARM_NV; } case CCmode: @@ -17738,13 +17738,22 @@ get_arm_condition_code (rtx comparison) case GTU: return ARM_HI; case LEU: return ARM_LS; case LTU: return ARM_CC; - default: gcc_unreachable (); + default: return ARM_NV; } default: gcc_unreachable (); } } +/* Like maybe_get_arm_condition_code, but never return ARM_NV. */ +static enum arm_cond_code +get_arm_condition_code (rtx comparison) +{ + enum arm_cond_code code = maybe_get_arm_condition_code (comparison); + gcc_assert (code != ARM_NV); + return code; +} + /* Tell arm_asm_output_opcode to output IT blocks for conditionally executed instructions. */ void Index: gcc/config/arm/predicates.md =================================================================== --- gcc/config/arm/predicates.md 2011-09-02 15:46:44.013865635 +0100 +++ gcc/config/arm/predicates.md 2011-09-02 15:56:35.764477233 +0100 @@ -249,10 +249,9 @@ (define_special_predicate "equality_oper ;; True for integer comparisons and, if FP is active, for comparisons ;; other than LTGT or UNEQ. (define_special_predicate "arm_comparison_operator" - (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu") - (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT - && (TARGET_FPA || TARGET_VFP)") - (match_code "unordered,ordered,unlt,unle,unge,ungt")))) + (and (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu, + unordered,ordered,unlt,unle,unge,ungt") + (match_test "maybe_get_arm_condition_code (op) != ARM_NV"))) (define_special_predicate "lt_ge_comparison_operator" (match_code "lt,ge")) Index: gcc/testsuite/gcc.dg/torture/pr49030.c =================================================================== --- /dev/null 2011-08-09 12:56:23.674000002 +0100 +++ gcc/testsuite/gcc.dg/torture/pr49030.c 2011-09-02 15:56:42.803460791 +0100 @@ -0,0 +1,19 @@ +void +sample_move_d32u24_sS (char *dst, float *src, unsigned long nsamples, + unsigned long dst_skip) +{ + long long y; + while (nsamples--) + { + y = (long long) (*src * 8388608.0f) << 8; + if (y > 2147483647) { + *(int *) dst = 2147483647; + } else if (y < -2147483647 - 1) { + *(int *) dst = -2147483647 - 1; + } else { + *(int *) dst = (int) y; + } + dst += dst_skip; + src++; + } +}