From patchwork Tue Aug 25 09:37:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Andre Vieira (lists)" X-Patchwork-Id: 510421 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 E587B1401EF for ; Tue, 25 Aug 2015 19:37:58 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=tp8x3Ei7; 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 :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=CSkiVdEGfGXS+gKZux/pmzJk+JGZcHvz1fTdpWSodQdjS2 xBIPHvltUx9w4geNfGd5DYOdVJa7oTFoTNy/ieHaYwEbjhD/uSbtIs+BONBDAuDZ HUwWBoEi24QULKpX1aavU3nOFzop9FTz0NcRM5g3WaoOCm+jLBlXwiDnWEG20= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=JL0R1BxXlWHwNGQaslGsYk1OGcw=; b=tp8x3Ei7dUtNoMITrNEc wH6C390h4/r7iPP4j1p1bDko9Hk00Mh2YVRnX79uGTFO0R2lNsEwE3zU7TeOJ1YC Idxem/TtRp8uSTMI/1+FymSyreWgY7FOibkqFxRyOxev+HnQOIZw9644M1UPrbTF z+BdINZK0Nt5ngXhHfje6is= Received: (qmail 15433 invoked by alias); 25 Aug 2015 09:37:48 -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 15424 invoked by uid 89); 25 Aug 2015 09:37:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_LOTSOFHASH, SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 25 Aug 2015 09:37:41 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-12-XD5uksi7TveIe-8gZNeGcQ-1; Tue, 25 Aug 2015 10:37:34 +0100 Received: from [10.2.207.8] ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 25 Aug 2015 10:37:33 +0100 Message-ID: <55DC375D.8060904@arm.com> Date: Tue, 25 Aug 2015 10:37:33 +0100 From: Andre Vieira User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [PATCH][AARCH64]Fix for branch offsets over 1 MiB X-MC-Unique: XD5uksi7TveIe-8gZNeGcQ-1 X-IsSubscribed: yes Conditional branches have a maximum range of [-1048576, 1048572]. Any destination further away can not be reached by these. To be able to have conditional branches in very large functions, we invert the condition and change the destination to jump over an unconditional branch to the original, far away, destination. gcc/ChangeLog: 2015-08-07 Ramana Radhakrishnan Andre Vieira * config/aarch64/aarch64.md (*condjump): Handle functions > 1 Mib. (*cb1): Idem. (*tb1): Idem. (*cb1): Idem. * config/aarch64/iterators.md (inv_cb): New code attribute. (inv_tb): Idem. * config/aarch64/aarch64.c (aarch64_gen_far_branch): New. * config/aarch64/aarch64-protos.h (aarch64_gen_far_branch): New. gcc/testsuite/ChangeLog: 2015-08-07 Andre Vieira * gcc.target/aarch64/long-branch.c: New test. From 9759c5a50c44b0421c7911014e63a6222dd9017d Mon Sep 17 00:00:00 2001 From: Andre Simoes Dias Vieira Date: Fri, 14 Aug 2015 10:21:57 +0100 Subject: [PATCH] fix for far branches --- gcc/config/aarch64/aarch64-protos.h | 1 + gcc/config/aarch64/aarch64.c | 23 + gcc/config/aarch64/aarch64.md | 89 +++- gcc/config/aarch64/iterators.md | 6 + gcc/testsuite/gcc.target/aarch64/long_branch.c | 565 +++++++++++++++++++++++++ 5 files changed, 669 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/long_branch.c diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 32b5d0958a6e0b2356874736f858f007fe68cdda..87a26deb6a0dbf13e25275baeebec21a37a42f41 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -316,6 +316,7 @@ unsigned aarch64_trampoline_size (void); void aarch64_asm_output_labelref (FILE *, const char *); void aarch64_cpu_cpp_builtins (cpp_reader *); void aarch64_elf_asm_named_section (const char *, unsigned, tree); +const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *); void aarch64_err_no_fpadvsimd (machine_mode, const char *); void aarch64_expand_epilogue (bool); void aarch64_expand_mov_immediate (rtx, rtx); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 7159f5aca5df97f154b3e654f60af9136354f335..3b491a232d81892b6511bad84e4174d939fa1be7 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -587,6 +587,29 @@ static const char * const aarch64_condition_codes[] = "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" }; +/* Generate code to enable conditional branches in functions over 1 MiB. */ +const char * +aarch64_gen_far_branch (rtx * operands, int pos_label, const char * dest, + const char * branch_format) +{ + rtx_code_label * tmp_label = gen_label_rtx (); + char label_buf[256]; + char buffer[128]; + ASM_GENERATE_INTERNAL_LABEL (label_buf, dest, + CODE_LABEL_NUMBER (tmp_label)); + const char *label_ptr = targetm.strip_name_encoding (label_buf); + rtx dest_label = operands[pos_label]; + operands[pos_label] = tmp_label; + + snprintf (buffer, sizeof (buffer), "%s%s", branch_format, label_ptr); + output_asm_insn (buffer, operands); + + snprintf (buffer, sizeof (buffer), "b\t%%l%d\n%s:", pos_label, label_ptr); + operands[pos_label] = dest_label; + output_asm_insn (buffer, operands); + return ""; +} + void aarch64_err_no_fpadvsimd (machine_mode mode, const char *msg) { diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 35255e91a95cdf20d52270470202f7499ba46bb2..74f6e3ec4bdcd076c2ad6d1431102aa50dfb5068 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -181,6 +181,13 @@ (const_string "no") ] (const_string "yes"))) +;; Attribute that specifies whether we are dealing with a branch to a +;; label that is far away, i.e. further away than the maximum/minimum +;; representable in a signed 21-bits number. +;; 0 :=: no +;; 1 :=: yes +(define_attr "far_branch" "" (const_int 0)) + ;; ------------------------------------------------------------------- ;; Pipeline descriptions and scheduling ;; ------------------------------------------------------------------- @@ -308,8 +315,23 @@ (label_ref (match_operand 2 "" "")) (pc)))] "" - "b%m0\\t%l2" - [(set_attr "type" "branch")] + { + if (get_attr_length (insn) == 8) + return aarch64_gen_far_branch (operands, 2, "Lbcond", "b%M0\\t"); + else + return "b%m0\\t%l2"; + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) + (lt (minus (match_dup 2) (pc)) (const_int 1048572))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) + (lt (minus (match_dup 2) (pc)) (const_int 1048572))) + (const_int 0) + (const_int 1)))] ) (define_expand "casesi" @@ -488,9 +510,23 @@ (label_ref (match_operand 1 "" "")) (pc)))] "" - "\\t%0, %l1" - [(set_attr "type" "branch")] - + { + if (get_attr_length (insn) == 8) + return aarch64_gen_far_branch (operands, 1, "Lcb", "\\t%0, "); + else + return "\\t%0, %l1"; + } + [(set_attr "type" "branch") + (set (attr "length") + (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576)) + (lt (minus (match_dup 1) (pc)) (const_int 1048572))) + (const_int 4) + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) + (lt (minus (match_dup 2) (pc)) (const_int 1048572))) + (const_int 0) + (const_int 1)))] ) (define_insn "*tb1" @@ -506,8 +542,14 @@ { if (get_attr_length (insn) == 8) { - operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); - return "tst\t%0, %1\;\t%l2"; + if (get_attr_far_branch (insn) == 1) + return aarch64_gen_far_branch (operands, 2, "Ltb", + "\\t%0, %1, "); + else + { + operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); + return "tst\t%0, %1\;\t%l2"; + } } else return "\t%0, %1, %l2"; @@ -517,7 +559,13 @@ (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) (lt (minus (match_dup 2) (pc)) (const_int 32764))) (const_int 4) - (const_int 8)))] + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576)) + (lt (minus (match_dup 2) (pc)) (const_int 1048572))) + (const_int 0) + (const_int 1)))] + ) (define_insn "*cb1" @@ -530,12 +578,18 @@ { if (get_attr_length (insn) == 8) { - char buf[64]; - uint64_t val = ((uint64_t ) 1) - << (GET_MODE_SIZE (mode) * BITS_PER_UNIT - 1); - sprintf (buf, "tst\t%%0, %" PRId64, val); - output_asm_insn (buf, operands); - return "\t%l1"; + if (get_attr_far_branch (insn) == 1) + return aarch64_gen_far_branch (operands, 1, "Ltb", + "\\t%0, , "); + else + { + char buf[64]; + uint64_t val = ((uint64_t) 1) + << (GET_MODE_SIZE (mode) * BITS_PER_UNIT - 1); + sprintf (buf, "tst\t%%0, %" PRId64, val); + output_asm_insn (buf, operands); + return "\t%l1"; + } } else return "\t%0, , %l1"; @@ -545,7 +599,12 @@ (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768)) (lt (minus (match_dup 1) (pc)) (const_int 32764))) (const_int 4) - (const_int 8)))] + (const_int 8))) + (set (attr "far_branch") + (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576)) + (lt (minus (match_dup 1) (pc)) (const_int 1048572))) + (const_int 0) + (const_int 1)))] ) ;; ------------------------------------------------------------------- diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 5d7966d7adf49a1824ddc41cd34b04c6f179b09a..8b245c351f11960267d242892fcddb68b1542ddb 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -820,9 +820,15 @@ ;; Emit cbz/cbnz depending on comparison type. (define_code_attr cbz [(eq "cbz") (ne "cbnz") (lt "cbnz") (ge "cbz")]) +;; Emit inverted cbz/cbnz depending on comparison type. +(define_code_attr inv_cb [(eq "cbnz") (ne "cbz") (lt "cbz") (ge "cbnz")]) + ;; Emit tbz/tbnz depending on comparison type. (define_code_attr tbz [(eq "tbz") (ne "tbnz") (lt "tbnz") (ge "tbz")]) +;; Emit inverted tbz/tbnz depending on comparison type. +(define_code_attr inv_tb [(eq "tbnz") (ne "tbz") (lt "tbz") (ge "tbnz")]) + ;; Max/min attributes. (define_code_attr maxmin [(smax "max") (smin "min") diff --git a/gcc/testsuite/gcc.target/aarch64/long_branch.c b/gcc/testsuite/gcc.target/aarch64/long_branch.c new file mode 100644 index 0000000000000000000000000000000000000000..37aed8823d3a3634be2462d0c18a9301c59ec97d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/long_branch.c @@ -0,0 +1,565 @@ +/* { dg-do assemble } */ +/* { dg-timeout-factor 2.0 } */ +/* { dg-options "-O1 -fno-reorder-blocks -fno-tree-cselim --save-temps" } */ + + +__attribute__((noinline, noclone)) int +restore (int a, int b) +{ + return a * b; +} + +__attribute__((noinline, noclone)) void +do_nothing (int *input) +{ + *input = restore (*input, 1); + return; +} + +#define CASE_ENTRY(n) \ + case n: \ + sum = sum / (n + 1); \ + sum = restore (sum, n + 1); \ + if (sum == (n + addend)) \ + break;\ + sum = sum / (n + 2); \ + sum = restore (sum, n + 2); \ + sum = sum / (n + 3); \ + sum = restore (sum, n + 3); \ + sum = sum / (n + 4); \ + sum = restore (sum, n + 4); \ + sum = sum / (n + 5); \ + sum = restore (sum, n + 5); \ + sum = sum / (n + 6); \ + sum = restore (sum, n + 6); \ + sum = sum / (n + 7); \ + sum = restore (sum, n + 7); \ + sum = sum / (n + 8); \ + sum = restore (sum, n + 8); \ + sum = sum / (n + 9); \ + sum = restore (sum, n + 9); \ + sum = sum / (n + 10); \ + sum = restore (sum, n + 10); \ + sum = sum / (n + 11); \ + sum = restore (sum, n + 11); \ + sum = sum / (n + 12); \ + sum = restore (sum, n + 12); \ + sum = sum / (n + 13); \ + sum = restore (sum, n + 13); \ + sum = sum / (n + 14); \ + sum = restore (sum, n + 14); \ + sum = sum / (n + 15); \ + sum = restore (sum, n + 15); \ + sum = sum / (n + 16); \ + sum = restore (sum, n + 16); \ + sum = sum / (n + 17); \ + sum = restore (sum, n + 17); \ + sum = sum / (n + 18); \ + sum = restore (sum, n + 18); \ + sum = sum / (n + 19); \ + sum = restore (sum, n + 19); \ + sum = sum / (n + 20); \ + sum = restore (sum, n + 20); \ + sum = sum / (n + 21); \ + sum = restore (sum, n + 21); \ + sum = sum / (n + 22); \ + sum = restore (sum, n + 22); \ + sum = sum / (n + 23); \ + sum = restore (sum, n + 23); \ + sum = sum / (n + 24); \ + sum = restore (sum, n + 24); \ + sum = sum / (n + 25); \ + sum = restore (sum, n + 25); \ + sum = sum / (n + 26); \ + sum = restore (sum, n + 26); \ + sum = sum / (n + 27); \ + sum = restore (sum, n + 27); \ + sum = sum / (n + 28); \ + sum = restore (sum, n + 28); \ + sum = sum / (n + 29); \ + sum = restore (sum, n + 29); \ + sum = sum / (n + 30); \ + sum = restore (sum, n + 30); \ + sum = sum / (n + 31); \ + sum = restore (sum, n + 31); \ + sum = sum / (n + 32); \ + sum = restore (sum, n + 32); \ + sum = sum / (n + 33); \ + sum = restore (sum, n + 33); \ + sum = sum / (n + 34); \ + sum = restore (sum, n + 34); \ + sum = sum / (n + 35); \ + sum = restore (sum, n + 35); \ + sum = sum / (n + 36); \ + sum = restore (sum, n + 36); \ + sum = sum / (n + 37); \ + sum = restore (sum, n + 37); \ + sum = sum / (n + 38); \ + sum = restore (sum, n + 38); \ + sum = sum / (n + 39); \ + sum = restore (sum, n + 39); \ + sum = sum / (n + 40); \ + sum = restore (sum, n + 40); \ + sum = sum / (n + 41); \ + sum = restore (sum, n + 41); \ + sum = sum / (n + 42); \ + sum = restore (sum, n + 42); \ + sum = sum / (n + 43); \ + sum = restore (sum, n + 43); \ + sum = sum / (n + 44); \ + sum = restore (sum, n + 44); \ + sum = sum / (n + 45); \ + sum = restore (sum, n + 45); \ + sum = sum / (n + 46); \ + sum = restore (sum, n + 46); \ + sum = sum / (n + 47); \ + sum = restore (sum, n + 47); \ + sum = sum / (n + 48); \ + sum = restore (sum, n + 48); \ + sum = sum / (n + 49); \ + sum = restore (sum, n + 49); \ + sum = sum / (n + 50); \ + sum = restore (sum, n + 50); \ + sum = sum / (n + 51); \ + sum = restore (sum, n + 51); \ + sum = sum / (n + 52); \ + sum = restore (sum, n + 52); \ + sum = sum / (n + 53); \ + sum = restore (sum, n + 53); \ + sum = sum / (n + 54); \ + sum = restore (sum, n + 54); \ + sum = sum / (n + 55); \ + sum = restore (sum, n + 55); \ + sum = sum / (n + 56); \ + sum = restore (sum, n + 56); \ + sum = sum / (n + 57); \ + sum = restore (sum, n + 57); \ + sum = sum / (n + 58); \ + sum = restore (sum, n + 58); \ + sum = sum / (n + 59); \ + sum = restore (sum, n + 59); \ + sum = sum / (n + 60); \ + sum = restore (sum, n + 60); \ + sum = sum / (n + 61); \ + sum = restore (sum, n + 61); \ + sum = sum / (n + 62); \ + sum = restore (sum, n + 62); \ + sum = sum / (n + 63); \ + sum = restore (sum, n + 63); \ + sum = sum / (n + 64); \ + sum = restore (sum, n + 64); \ + sum = sum / (n + 65); \ + sum = restore (sum, n + 65); \ + sum = sum / (n + 66); \ + sum = restore (sum, n + 66); \ + sum = sum / (n + 67); \ + sum = restore (sum, n + 67); \ + sum = sum / (n + 68); \ + sum = restore (sum, n + 68); \ + sum = sum / (n + 69); \ + sum = restore (sum, n + 69); \ + sum = sum / (n + 70); \ + sum = restore (sum, n + 70); \ + sum = sum / (n + 71); \ + sum = restore (sum, n + 71); \ + sum = sum / (n + 72); \ + sum = restore (sum, n + 72); \ + sum = sum / (n + 73); \ + sum = restore (sum, n + 73); \ + sum = sum / (n + 74); \ + sum = restore (sum, n + 74); \ + sum = sum / (n + 75); \ + sum = restore (sum, n + 75); \ + sum = sum / (n + 76); \ + sum = restore (sum, n + 76); \ + sum = sum / (n + 77); \ + sum = restore (sum, n + 77); \ + sum = sum / (n + 78); \ + sum = restore (sum, n + 78); \ + sum = sum / (n + 79); \ + sum = restore (sum, n + 79); \ + sum = sum / (n + 80); \ + sum = restore (sum, n + 80); \ + sum = sum / (n + 81); \ + sum = restore (sum, n + 81); \ + sum = sum / (n + 82); \ + sum = restore (sum, n + 82); \ + sum = sum / (n + 83); \ + sum = restore (sum, n + 83); \ + sum = sum / (n + 84); \ + sum = restore (sum, n + 84); \ + sum = sum / (n + 85); \ + sum = restore (sum, n + 85); \ + sum = sum / (n + 86); \ + sum = restore (sum, n + 86); \ + sum = sum / (n + 87); \ + sum = restore (sum, n + 87); \ + sum = sum / (n + 88); \ + sum = restore (sum, n + 88); \ + sum = sum / (n + 89); \ + sum = restore (sum, n + 89); \ + sum = sum / (n + 90); \ + sum = restore (sum, n + 90); \ + sum = sum / (n + 91); \ + sum = restore (sum, n + 91); \ + sum = sum / (n + 92); \ + sum = restore (sum, n + 92); \ + sum = sum / (n + 93); \ + sum = restore (sum, n + 93); \ + sum = sum / (n + 94); \ + sum = restore (sum, n + 94); \ + sum = sum / (n + 95); \ + sum = restore (sum, n + 95); \ + sum = sum / (n + 96); \ + sum = restore (sum, n + 96); \ + sum = sum / (n + 97); \ + sum = restore (sum, n + 97); \ + sum = sum / (n + 98); \ + sum = restore (sum, n + 98); \ + sum = sum / (n + 99); \ + sum = restore (sum, n + 99); \ + sum = sum / (n + 100); \ + sum = restore (sum, n + 100); \ + sum = sum / (n + 101); \ + sum = restore (sum, n + 101); \ + sum = sum / (n + 102); \ + sum = restore (sum, n + 102); \ + sum = sum / (n + 103); \ + sum = restore (sum, n + 103); \ + sum = sum / (n + 104); \ + sum = restore (sum, n + 104); \ + sum = sum / (n + 105); \ + sum = restore (sum, n + 105); \ + sum = sum / (n + 106); \ + sum = restore (sum, n + 106); \ + sum = sum / (n + 107); \ + sum = restore (sum, n + 107); \ + sum = sum / (n + 108); \ + sum = restore (sum, n + 108); \ + sum = sum / (n + 109); \ + sum = restore (sum, n + 109); \ + sum = sum / (n + 110); \ + sum = restore (sum, n + 110); \ + sum = sum / (n + 111); \ + sum = restore (sum, n + 111); \ + sum = sum / (n + 112); \ + sum = restore (sum, n + 112); \ + sum = sum / (n + 113); \ + sum = restore (sum, n + 113); \ + sum = sum / (n + 114); \ + sum = restore (sum, n + 114); \ + sum = sum / (n + 115); \ + sum = restore (sum, n + 115); \ + sum = sum / (n + 116); \ + sum = restore (sum, n + 116); \ + sum = sum / (n + 117); \ + sum = restore (sum, n + 117); \ + sum = sum / (n + 118); \ + sum = restore (sum, n + 118); \ + sum = sum / (n + 119); \ + sum = restore (sum, n + 119); \ + sum = sum / (n + 120); \ + sum = restore (sum, n + 120); \ + sum = sum / (n + 121); \ + sum = restore (sum, n + 121); \ + sum = sum / (n + 122); \ + sum = restore (sum, n + 122); \ + sum = sum / (n + 123); \ + sum = restore (sum, n + 123); \ + sum = sum / (n + 124); \ + sum = restore (sum, n + 124); \ + sum = sum / (n + 125); \ + sum = restore (sum, n + 125); \ + sum = sum / (n + 126); \ + sum = restore (sum, n + 126); \ + sum = sum / (n + 127); \ + sum = restore (sum, n + 127); \ + sum = sum / (n + 128); \ + sum = restore (sum, n + 128); \ + sum = sum / (n + 129); \ + sum = restore (sum, n + 129); \ + sum = sum / (n + 130); \ + sum = restore (sum, n + 130); \ + sum = sum / (n + 131); \ + sum = restore (sum, n + 131); \ + sum = sum / (n + 132); \ + sum = restore (sum, n + 132); \ + sum = sum / (n + 133); \ + sum = restore (sum, n + 133); \ + sum = sum / (n + 134); \ + sum = restore (sum, n + 134); \ + sum = sum / (n + 135); \ + sum = restore (sum, n + 135); \ + sum = sum / (n + 136); \ + sum = restore (sum, n + 136); \ + sum = sum / (n + 137); \ + sum = restore (sum, n + 137); \ + sum = sum / (n + 138); \ + sum = restore (sum, n + 138); \ + sum = sum / (n + 139); \ + sum = restore (sum, n + 139); \ + sum = sum / (n + 140); \ + sum = restore (sum, n + 140); \ + sum = sum / (n + 141); \ + sum = restore (sum, n + 141); \ + sum = sum / (n + 142); \ + sum = restore (sum, n + 142); \ + sum = sum / (n + 143); \ + sum = restore (sum, n + 143); \ + sum = sum / (n + 144); \ + sum = restore (sum, n + 144); \ + sum = sum / (n + 145); \ + sum = restore (sum, n + 145); \ + sum = sum / (n + 146); \ + sum = restore (sum, n + 146); \ + sum = sum / (n + 147); \ + sum = restore (sum, n + 147); \ + sum = sum / (n + 148); \ + sum = restore (sum, n + 148); \ + sum = sum / (n + 149); \ + sum = restore (sum, n + 149); \ + sum = sum / (n + 150); \ + sum = restore (sum, n + 150); \ + break; + +__attribute__((noinline, noclone)) long long +test_and_branch (int selector, int addend, int cond) +{ + long long sum = selector + 1; + + if (selector > 200) + { +start0: + return sum - 1; +start1: + return sum + 1; +start2: + return sum; +start3: + return sum - 2; + } + else + { + switch (selector) + { + CASE_ENTRY (1) + CASE_ENTRY (2) + CASE_ENTRY (3) + CASE_ENTRY (4) + CASE_ENTRY (5) + CASE_ENTRY (6) + CASE_ENTRY (7) + CASE_ENTRY (8) + CASE_ENTRY (9) + CASE_ENTRY (10) + CASE_ENTRY (11) + CASE_ENTRY (12) + CASE_ENTRY (13) + CASE_ENTRY (14) + CASE_ENTRY (15) + CASE_ENTRY (16) + CASE_ENTRY (17) + CASE_ENTRY (18) + CASE_ENTRY (19) + CASE_ENTRY (20) + CASE_ENTRY (21) + CASE_ENTRY (22) + CASE_ENTRY (23) + CASE_ENTRY (24) + CASE_ENTRY (25) + CASE_ENTRY (26) + CASE_ENTRY (27) + CASE_ENTRY (28) + CASE_ENTRY (29) + CASE_ENTRY (30) + CASE_ENTRY (31) + CASE_ENTRY (32) + CASE_ENTRY (33) + CASE_ENTRY (34) + CASE_ENTRY (35) + CASE_ENTRY (36) + CASE_ENTRY (37) + CASE_ENTRY (38) + CASE_ENTRY (39) + CASE_ENTRY (40) + CASE_ENTRY (41) + CASE_ENTRY (42) + CASE_ENTRY (43) + CASE_ENTRY (44) + CASE_ENTRY (45) + CASE_ENTRY (46) + CASE_ENTRY (47) + CASE_ENTRY (48) + CASE_ENTRY (49) + CASE_ENTRY (50) + CASE_ENTRY (51) + CASE_ENTRY (52) + CASE_ENTRY (53) + CASE_ENTRY (54) + CASE_ENTRY (55) + CASE_ENTRY (56) + CASE_ENTRY (57) + CASE_ENTRY (58) + CASE_ENTRY (59) + CASE_ENTRY (60) + CASE_ENTRY (61) + CASE_ENTRY (62) + CASE_ENTRY (63) + CASE_ENTRY (64) + CASE_ENTRY (65) + CASE_ENTRY (66) + CASE_ENTRY (67) + CASE_ENTRY (68) + CASE_ENTRY (69) + CASE_ENTRY (70) + CASE_ENTRY (71) + CASE_ENTRY (72) + CASE_ENTRY (73) + CASE_ENTRY (74) + CASE_ENTRY (75) + CASE_ENTRY (76) + CASE_ENTRY (77) + CASE_ENTRY (78) + CASE_ENTRY (79) + CASE_ENTRY (80) + CASE_ENTRY (81) + CASE_ENTRY (82) + CASE_ENTRY (83) + CASE_ENTRY (84) + CASE_ENTRY (85) + CASE_ENTRY (86) + CASE_ENTRY (87) + CASE_ENTRY (88) + CASE_ENTRY (89) + CASE_ENTRY (90) + CASE_ENTRY (91) + CASE_ENTRY (92) + CASE_ENTRY (93) + CASE_ENTRY (94) + CASE_ENTRY (95) + CASE_ENTRY (96) + CASE_ENTRY (97) + CASE_ENTRY (98) + CASE_ENTRY (99) + CASE_ENTRY (100) + CASE_ENTRY (101) + CASE_ENTRY (102) + CASE_ENTRY (103) + CASE_ENTRY (104) + CASE_ENTRY (105) + CASE_ENTRY (106) + CASE_ENTRY (107) + CASE_ENTRY (108) + CASE_ENTRY (109) + CASE_ENTRY (110) + CASE_ENTRY (111) + CASE_ENTRY (112) + CASE_ENTRY (113) + CASE_ENTRY (114) + CASE_ENTRY (115) + CASE_ENTRY (116) + CASE_ENTRY (117) + CASE_ENTRY (118) + CASE_ENTRY (119) + CASE_ENTRY (120) + CASE_ENTRY (121) + CASE_ENTRY (122) + CASE_ENTRY (123) + CASE_ENTRY (124) + CASE_ENTRY (125) + CASE_ENTRY (126) + CASE_ENTRY (127) + CASE_ENTRY (128) + CASE_ENTRY (129) + CASE_ENTRY (130) + CASE_ENTRY (131) + CASE_ENTRY (132) + CASE_ENTRY (133) + CASE_ENTRY (134) + CASE_ENTRY (135) + CASE_ENTRY (136) + CASE_ENTRY (137) + CASE_ENTRY (138) + CASE_ENTRY (139) + CASE_ENTRY (140) + CASE_ENTRY (141) + CASE_ENTRY (142) + CASE_ENTRY (143) + CASE_ENTRY (144) + CASE_ENTRY (145) + CASE_ENTRY (146) + CASE_ENTRY (147) + CASE_ENTRY (148) + CASE_ENTRY (149) + CASE_ENTRY (150) + CASE_ENTRY (151) + CASE_ENTRY (152) + CASE_ENTRY (153) + CASE_ENTRY (154) + CASE_ENTRY (155) + CASE_ENTRY (156) + CASE_ENTRY (157) + CASE_ENTRY (158) + CASE_ENTRY (159) + CASE_ENTRY (160) + CASE_ENTRY (161) + CASE_ENTRY (162) + CASE_ENTRY (163) + CASE_ENTRY (164) + CASE_ENTRY (165) + CASE_ENTRY (166) + CASE_ENTRY (167) + CASE_ENTRY (168) + CASE_ENTRY (169) + CASE_ENTRY (170) + CASE_ENTRY (171) + CASE_ENTRY (172) + CASE_ENTRY (173) + CASE_ENTRY (174) + CASE_ENTRY (175) + CASE_ENTRY (176) + CASE_ENTRY (177) + CASE_ENTRY (178) + CASE_ENTRY (179) + CASE_ENTRY (180) + CASE_ENTRY (181) + CASE_ENTRY (182) + CASE_ENTRY (183) + CASE_ENTRY (184) + CASE_ENTRY (185) + CASE_ENTRY (186) + CASE_ENTRY (187) + CASE_ENTRY (188) + CASE_ENTRY (189) + CASE_ENTRY (190) + CASE_ENTRY (191) + CASE_ENTRY (192) + CASE_ENTRY (193) + CASE_ENTRY (194) + CASE_ENTRY (195) + CASE_ENTRY (196) + CASE_ENTRY (197) + CASE_ENTRY (198) + CASE_ENTRY (199) + CASE_ENTRY (200) + } + + do_nothing ((int *)&sum); + + if (cond == 0) + goto start0; + else if (cond < 0) + goto start1; + else if ((cond & 0x010) != 0) + goto start2; + else if (cond >= 14) + goto start3; + + } + + return -1; +} + +/* { dg-final { scan-assembler "Lbcond" } } */ +/* { dg-final { scan-assembler "Lcb" } } */ +/* { dg-final { scan-assembler "Ltb" } } */ -- 1.9.1