From patchwork Thu Aug 19 15:49:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 62182 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]) by ozlabs.org (Postfix) with SMTP id 67574B70EF for ; Fri, 20 Aug 2010 01:49:48 +1000 (EST) Received: (qmail 10409 invoked by alias); 19 Aug 2010 15:49:47 -0000 Received: (qmail 10399 invoked by uid 22791); 19 Aug 2010 15:49:45 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, TW_ZJ, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 19 Aug 2010 15:49:40 +0000 Received: by qwd7 with SMTP id 7so244610qwd.20 for ; Thu, 19 Aug 2010 08:49:38 -0700 (PDT) MIME-Version: 1.0 Received: by 10.224.28.211 with SMTP id n19mr6616260qac.318.1282232978352; Thu, 19 Aug 2010 08:49:38 -0700 (PDT) Received: by 10.229.182.18 with HTTP; Thu, 19 Aug 2010 08:49:38 -0700 (PDT) Date: Thu, 19 Aug 2010 17:49:38 +0200 Message-ID: Subject: [PATCH, i386]: Some further LEA fixes/improvements From: Uros Bizjak To: gcc-patches@gcc.gnu.org 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 Hello! Just fixes and improves a bit LEA patterns. 2010-08-19 Uros Bizjak * config/i386/i386.md (*lea_1): Use P mode iterator. (lea add splitter): Also handle DImode operands. (DImode lea add splitter): Use x86_64_immediate_operand for operand 2 predicate. Do not use ix86_lea_for_add_ok. (zext DImode lea add splitter): Use ix86_lea_for_add_ok. (lea ashift splitter): Also handle DImode operands. (DImode lea ashift splitter): Remove splitter. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline. Uros. Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 163363) +++ config/i386/i386.md (working copy) @@ -5764,8 +5764,8 @@ (set_attr "mode" "QI")]) (define_insn "*lea_1" - [(set (match_operand:DWIH 0 "register_operand" "=r") - (match_operand:DWIH 1 "no_seg_address_operand" "p"))] + [(set (match_operand:P 0 "register_operand" "=r") + (match_operand:P 1 "no_seg_address_operand" "p"))] "" "lea{}\t{%a1, %0|%0, %a1}" [(set_attr "type" "lea") @@ -6137,6 +6137,68 @@ (const_string "none"))) (set_attr "mode" "QI")]) +;; Convert lea to the lea pattern to avoid flags dependency. +(define_split + [(set (match_operand 0 "register_operand" "") + (plus (match_operand 1 "register_operand" "") + (match_operand 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))] + "reload_completed && ix86_lea_for_add_ok (insn, operands)" + [(const_int 0)] +{ + rtx pat; + enum machine_mode mode = GET_MODE (operands[0]); + + /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) + may confuse gen_lowpart. */ + if (mode != Pmode) + { + operands[1] = gen_lowpart (Pmode, operands[1]); + operands[2] = gen_lowpart (Pmode, operands[2]); + } + + pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); + + if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) + operands[0] = gen_lowpart (SImode, operands[0]); + + if (TARGET_64BIT && mode != Pmode) + pat = gen_rtx_SUBREG (SImode, pat, 0); + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); + DONE; +}) + +;; Convert lea to the lea pattern to avoid flags dependency. +;; ??? This pattern handles immediate operands that do not satisfy immediate +;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "x86_64_immediate_operand" ""))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && reload_completed + && true_regnum (operands[0]) != true_regnum (operands[1])" + [(set (match_dup 0) + (plus:DI (match_dup 1) (match_dup 2)))] + "") + +;; Convert lea to the lea pattern to avoid flags dependency. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI + (plus:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && reload_completed + && ix86_lea_for_add_ok (insn, operands)" + [(set (match_dup 0) + (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] +{ + operands[1] = gen_lowpart (DImode, operands[1]); + operands[2] = gen_lowpart (DImode, operands[2]); +}) + (define_insn "*add_2" [(set (reg FLAGS_REG) (compare @@ -6678,60 +6740,6 @@ } [(set_attr "type" "lea") (set_attr "mode" "SI")]) - -;; Convert lea to the lea pattern to avoid flags dependency. -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && ix86_lea_for_add_ok (insn, operands)" - [(set (match_dup 0) - (plus:DI (match_dup 1) - (match_dup 2)))] - "") - -;; Convert lea to the lea pattern to avoid flags dependency. -(define_split - [(set (match_operand 0 "register_operand" "") - (plus (match_operand 1 "register_operand" "") - (match_operand 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "reload_completed && ix86_lea_for_add_ok (insn, operands)" - [(const_int 0)] -{ - rtx pat; - /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) - may confuse gen_lowpart. */ - if (GET_MODE (operands[0]) != Pmode) - { - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_lowpart (Pmode, operands[2]); - } - operands[0] = gen_lowpart (SImode, operands[0]); - pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); - if (Pmode != SImode) - pat = gen_rtx_SUBREG (SImode, pat, 0); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); - DONE; -}) - -;; Convert lea to the lea pattern to avoid flags dependency. -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1])" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] -{ - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_lowpart (Pmode, operands[2]); -}) ;; Subtract instructions @@ -9586,44 +9594,49 @@ ;; Convert lea to the lea pattern to avoid flags dependency. (define_split - [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "index_register_operand" "") - (match_operand:QI 2 "const_int_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1])" - [(set (match_dup 0) - (mult:DI (match_dup 1) - (match_dup 2)))] - "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") - -;; Convert lea to the lea pattern to avoid flags dependency. -(define_split [(set (match_operand 0 "register_operand" "") (ashift (match_operand 1 "index_register_operand" "") (match_operand:QI 2 "const_int_operand" ""))) (clobber (reg:CC FLAGS_REG))] "reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1]) - && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" + && true_regnum (operands[0]) != true_regnum (operands[1])" [(const_int 0)] { rtx pat; enum machine_mode mode = GET_MODE (operands[0]); - if (GET_MODE_SIZE (mode) < 4) - operands[0] = gen_lowpart (SImode, operands[0]); if (mode != Pmode) operands[1] = gen_lowpart (Pmode, operands[1]); operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); - if (Pmode != SImode) + + if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) + operands[0] = gen_lowpart (SImode, operands[0]); + + if (TARGET_64BIT && mode != Pmode) pat = gen_rtx_SUBREG (SImode, pat, 0); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; }) +;; Convert lea to the lea pattern to avoid flags dependency. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI + (ashift:SI (match_operand:SI 1 "index_register_operand" "") + (match_operand:QI 2 "const_int_operand" "")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && reload_completed + && true_regnum (operands[0]) != true_regnum (operands[1])" + [(set (match_dup 0) + (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))] +{ + operands[1] = gen_lowpart (DImode, operands[1]); + operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode); +}) + ;; Rare case of shifting RSP is handled by generating move and shift (define_split [(set (match_operand 0 "register_operand" "") @@ -9644,22 +9657,6 @@ DONE; }) -;; Convert lea to the lea pattern to avoid flags dependency. -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI - (ashift:SI (match_operand:SI 1 "register_operand" "") - (match_operand:QI 2 "const_int_operand" "")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1])" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))] -{ - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); -}) - ;; This pattern can't accept a variable shift count, since shifts by ;; zero don't affect the flags. We assume that shifts by constant ;; zero are optimized away.