From patchwork Thu Dec 15 22:34:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 706285 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 3tfpCd2ZW8z9sCM for ; Fri, 16 Dec 2016 09:34:35 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="QiaLBBpt"; 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 :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=f4uzbc0c6i40nvwXtvpO0pka6yIv7r7VVekvYeGgZXnceM f1nbGigcmwPRS74sXAsjJVXHLD7xqJM8JpMr4kxTRlEwscW5avmTLYz0ddrHSCu8 7eRug+NOorb6OQBS86kMBlQmcXmwFncacCPOpR6aDa9lIdMx8d8c36bVxQdak= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=7bRjcPx+5GwXrlblNZMcaWXI4i8=; b=QiaLBBpt7RcfL8ibNBcl aSzffvorKEuXTe0uQveU1+iv7E/d5Povhbtt/Ymu0pVQDnxX3Qi73pIc/3TgUDEi jrY//0KSRUIH/HCgpIEcA8QAznRIjLVJwUwQMgVx8Sz5yWt2a6IyvtXk/3kpXh8/ epgIVbd26GXTjhjMLPfmveI= Received: (qmail 47203 invoked by alias); 15 Dec 2016 22:34:23 -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 47189 invoked by uid 89); 15 Dec 2016 22:34:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.3 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 spammy=bdesc, BDESC, unspec, ubizjak@gmail.com X-HELO: mail-ua0-f174.google.com Received: from mail-ua0-f174.google.com (HELO mail-ua0-f174.google.com) (209.85.217.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 15 Dec 2016 22:34:12 +0000 Received: by mail-ua0-f174.google.com with SMTP id 51so21427034uai.1 for ; Thu, 15 Dec 2016 14:34:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Pbos0/NGySjXjwtSMLe6pzODH6oxnXCCUQUk9dbnImE=; b=kaargNb9T6UjjV2yQXHJDnarC9t9Cel+CbB6dYUijAAUFkAlZ+uYpTe3f9HIzqZWQb bXEH+ia2iVxVl4oF9e2K5CK5e9orlKpo1uNohx23WhEgNx/o8GbtYKFPiQgwqOD96xUI mP/77zFsqWa+ZeHzT9PDFEgReu/CIflgKGmmuG1Y//alIUwH82yovqmb2CIwu1e1coeG SgrDYaNXD3FzSu7ncd/VZg7Ul05g8fQM0mImt8IKRTrnp9t7sjGZOyfTnmZE8JgXhYyK hPCwiCoiV7D/Upt68aXXnk5aRqwzu2LxGuU1NlR4JrmEs7v1ZAm9TOSpAVgN4m98Jzk2 KSFg== X-Gm-Message-State: AKaTC03BDYNfB+Pxlyb6Mlyuol/eNb1QH6S3ybkyXYW1N2arBSBDub4f1LgPEc2XAFQCobYRSZT+LuE1t/397Q== X-Received: by 10.159.40.97 with SMTP id c88mr5016680uac.17.1481841250454; Thu, 15 Dec 2016 14:34:10 -0800 (PST) MIME-Version: 1.0 Received: by 10.103.135.215 with HTTP; Thu, 15 Dec 2016 14:34:09 -0800 (PST) From: Uros Bizjak Date: Thu, 15 Dec 2016 23:34:09 +0100 Message-ID: Subject: [PATCH, i386]: Improve ffs for TARGET_BMI and macroize a couple of bitmanip patterns To: "gcc-patches@gcc.gnu.org" Hello! Attached patch improves ffs expandsion for TARGET_BMI targets. Compared to bsf, tzcnt is noticeably faster on AMD processors. However, since generic target enables TARGET_AVOID_FALSE_DEP_FOR_BMI, we always expand ffs with bsf, even when using -mbmi. Attached patch enables TARGET_AVOID_FALSE_DEP_FOR_BMI fixup also for ffs expander, so tzcnt with eventual false-dep fixup is generated for generic -mbmi targets. The patch also macroizes a couple of patterns in this area. 2016-12-15 Uros Bizjak * config/i386/i386.md (ffs2): Generate CCCmode flags register for TARGET_BMI. (ffssi2_no_cmove): Ditto. (*tzcnt_1_falsedep_1): New insn_and_split pattern. (*tzcnt_1_falsedep): New insn pattern. (LT_ZCNT): New mode iterator. (lt_zcnt): New mode attribute. (lt_zcnt_type): New mode attribute. (_): Macroize expander from bmi_tzcnt_ and lzcnt_ using LT_ZCNT mode iterator. (*__falsedep_1): Macroize insn from *bmi_tzcnt__falsedep_1 and *lzcnt__falsedep_1 using LT_ZCNT mode iterator. (*__falsedep): Macroize insn from *bmi_tzcnt__falsedep and *lzcnt__falsedep using LT_ZCNT mode iterator. (*_): Macroize insn from *bmi_tzcnt_ and *lzcnt_ using LT_ZCNT mode iterator. * config/i386/i386-builtin.def (__builtin_ia32_tzcnt_u16) (__builtin_ia32_tzcnt_u32, __builtin_ia32_tzcnt_u64, __builtin_ctzs): Update for rename. Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros. Index: config/i386/i386-builtin.def =================================================================== --- config/i386/i386-builtin.def (revision 243716) +++ config/i386/i386-builtin.def (working copy) @@ -1197,11 +1197,11 @@ BDESC (OPTION_MASK_ISA_LZCNT | OPTION_MASK_ISA_64B BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_bmi_bextr_si, "__builtin_ia32_bextr_u32", IX86_BUILTIN_BEXTR32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT) BDESC (OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_64BIT, CODE_FOR_bmi_bextr_di, "__builtin_ia32_bextr_u64", IX86_BUILTIN_BEXTR64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64) -BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_bmi_tzcnt_hi, "__builtin_ia32_tzcnt_u16", IX86_BUILTIN_TZCNT16, UNKNOWN, (int) UINT16_FTYPE_UINT16) +BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_tzcnt_hi, "__builtin_ia32_tzcnt_u16", IX86_BUILTIN_TZCNT16, UNKNOWN, (int) UINT16_FTYPE_UINT16) /* Same as above, for backward compatibility. */ -BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_bmi_tzcnt_hi, "__builtin_ctzs", IX86_BUILTIN_CTZS, UNKNOWN, (int) UINT16_FTYPE_UINT16) -BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_bmi_tzcnt_si, "__builtin_ia32_tzcnt_u32", IX86_BUILTIN_TZCNT32, UNKNOWN, (int) UINT_FTYPE_UINT) -BDESC (OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_64BIT, CODE_FOR_bmi_tzcnt_di, "__builtin_ia32_tzcnt_u64", IX86_BUILTIN_TZCNT64, UNKNOWN, (int) UINT64_FTYPE_UINT64) +BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_tzcnt_hi, "__builtin_ctzs", IX86_BUILTIN_CTZS, UNKNOWN, (int) UINT16_FTYPE_UINT16) +BDESC (OPTION_MASK_ISA_BMI, CODE_FOR_tzcnt_si, "__builtin_ia32_tzcnt_u32", IX86_BUILTIN_TZCNT32, UNKNOWN, (int) UINT_FTYPE_UINT) +BDESC (OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_64BIT, CODE_FOR_tzcnt_di, "__builtin_ia32_tzcnt_u64", IX86_BUILTIN_TZCNT64, UNKNOWN, (int) UINT64_FTYPE_UINT64) /* TBM */ BDESC (OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_si, "__builtin_ia32_bextri_u32", IX86_BUILTIN_BEXTRI32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT) Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 243716) +++ config/i386/i386.md (working copy) @@ -12534,8 +12534,7 @@ DONE; } - flags_mode - = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode; + flags_mode = TARGET_BMI ? CCCmode : CCZmode; operands[2] = gen_reg_rtx (mode); operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); @@ -12561,8 +12560,7 @@ (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) (clobber (reg:CC FLAGS_REG))])] { - machine_mode flags_mode - = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode; + machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode; operands[3] = gen_lowpart (QImode, operands[2]); operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); @@ -12571,6 +12569,46 @@ ix86_expand_clear (operands[2]); }) +; False dependency happens when destination is only updated by tzcnt, +; lzcnt or popcnt. There is no false dependency when destination is +; also used in source. +(define_insn_and_split "*tzcnt_1_falsedep_1" + [(set (reg:CCC FLAGS_REG) + (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 0))) + (set (match_operand:SWI48 0 "register_operand" "=r") + (ctz:SWI48 (match_dup 1)))] + "TARGET_BMI + && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" + "#" + "&& reload_completed" + [(parallel + [(set (reg:CCC FLAGS_REG) + (compare:CCC (match_dup 1) (const_int 0))) + (set (match_dup 0) + (ctz:SWI48 (match_dup 1))) + (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] +{ + if (!reg_mentioned_p (operands[0], operands[1])) + ix86_expand_clear (operands[0]); +}) + +(define_insn "*tzcnt_1_falsedep" + [(set (reg:CCC FLAGS_REG) + (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 0))) + (set (match_operand:SWI48 0 "register_operand" "=r") + (ctz:SWI48 (match_dup 1))) + (unspec [(match_operand:SWI48 2 "register_operand" "0")] + UNSPEC_INSN_FALSE_DEP)] + "TARGET_BMI" + "tzcnt{}\t{%1, %0|%0, %1}"; + [(set_attr "type" "alu1") + (set_attr "prefix_0f" "1") + (set_attr "prefix_rep" "1") + (set_attr "btver2_decode" "double") + (set_attr "mode" "")]) + (define_insn "*tzcnt_1" [(set (reg:CCC FLAGS_REG) (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") @@ -12577,7 +12615,7 @@ (const_int 0))) (set (match_operand:SWI48 0 "register_operand" "=r") (ctz:SWI48 (match_dup 1)))] - "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI" + "TARGET_BMI" "tzcnt{}\t{%1, %0|%0, %1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") @@ -12619,7 +12657,7 @@ { rtx tmp = gen_reg_rtx (HImode); - emit_insn (gen_bmi_tzcnt_hi (tmp, operands[1])); + emit_insn (gen_tzcnt_hi (tmp, operands[1])); emit_insn (gen_zero_extendhisi2 (operands[0], tmp)); DONE; }) @@ -12695,68 +12733,41 @@ (const_string "0"))) (set_attr "mode" "")]) -;; Version of tzcnt that is expanded from intrinsics. This version provides -;; operand size as output when source operand is zero. - -(define_expand "bmi_tzcnt_" - [(parallel - [(set (match_operand:SWI248 0 "register_operand") - (unspec:SWI248 - [(match_operand:SWI248 1 "nonimmediate_operand")] - UNSPEC_TZCNT)) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_BMI") - -; False dependency happens when destination is only updated by tzcnt, -; lzcnt or popcnt. There is no false dependency when destination is -; also used in source. -(define_insn_and_split "*bmi_tzcnt__falsedep_1" - [(set (match_operand:SWI48 0 "register_operand" "=r") - (unspec:SWI48 - [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] - UNSPEC_TZCNT)) +(define_insn "bsr_rex64" + [(set (match_operand:DI 0 "register_operand" "=r") + (minus:DI (const_int 63) + (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_BMI - && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" - "#" - "&& reload_completed" - [(parallel - [(set (match_dup 0) - (unspec:SWI48 [(match_dup 1)] UNSPEC_TZCNT)) - (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) - (clobber (reg:CC FLAGS_REG))])] -{ - if (!reg_mentioned_p (operands[0], operands[1])) - ix86_expand_clear (operands[0]); -}) + "TARGET_64BIT" + "bsr{q}\t{%1, %0|%0, %1}" + [(set_attr "type" "alu1") + (set_attr "prefix_0f" "1") + (set_attr "znver1_decode" "vector") + (set_attr "mode" "DI")]) -(define_insn "*bmi_tzcnt__falsedep" - [(set (match_operand:SWI48 0 "register_operand" "=r") - (unspec:SWI48 - [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] - UNSPEC_TZCNT)) - (unspec [(match_operand:SWI48 2 "register_operand" "0")] - UNSPEC_INSN_FALSE_DEP) +(define_insn "bsr" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (const_int 31) + (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_BMI" - "tzcnt{}\t{%1, %0|%0, %1}" + "" + "bsr{l}\t{%1, %0|%0, %1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") - (set_attr "prefix_rep" "1") - (set_attr "mode" "")]) + (set_attr "znver1_decode" "vector") + (set_attr "mode" "SI")]) -(define_insn "*bmi_tzcnt_" - [(set (match_operand:SWI248 0 "register_operand" "=r") - (unspec:SWI248 - [(match_operand:SWI248 1 "nonimmediate_operand" "rm")] - UNSPEC_TZCNT)) +(define_insn "*bsrhi" + [(set (match_operand:HI 0 "register_operand" "=r") + (minus:HI (const_int 15) + (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_BMI" - "tzcnt{}\t{%1, %0|%0, %1}" + "" + "bsr{w}\t{%1, %0|%0, %1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") - (set_attr "prefix_rep" "1") - (set_attr "mode" "")]) + (set_attr "znver1_decode" "vector") + (set_attr "mode" "HI")]) (define_expand "clz2" [(parallel @@ -12778,14 +12789,6 @@ operands[2] = GEN_INT (GET_MODE_BITSIZE (mode)-1); }) -(define_expand "clz2_lzcnt" - [(parallel - [(set (match_operand:SWI48 0 "register_operand") - (clz:SWI48 - (match_operand:SWI48 1 "nonimmediate_operand"))) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_LZCNT") - (define_insn_and_split "*clzhi2" [(set (match_operand:SI 0 "register_operand") (clz:SI @@ -12839,9 +12842,10 @@ (set_attr "type" "bitmanip") (set_attr "mode" "")]) -(define_insn "*clz2_lzcnt" +(define_insn "clz2_lzcnt" [(set (match_operand:SWI48 0 "register_operand" "=r") - (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) + (clz:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_LZCNT" "lzcnt{}\t{%1, %0|%0, %1}" @@ -12849,34 +12853,42 @@ (set_attr "type" "bitmanip") (set_attr "mode" "")]) -;; Version of lzcnt that is expanded from intrinsics. This version provides -;; operand size as output when source operand is zero. +(define_int_iterator LT_ZCNT + [(UNSPEC_TZCNT "TARGET_BMI") + (UNSPEC_LZCNT "TARGET_LZCNT")]) -(define_expand "lzcnt_" +(define_int_attr lt_zcnt + [(UNSPEC_TZCNT "tzcnt") + (UNSPEC_LZCNT "lzcnt")]) + +(define_int_attr lt_zcnt_type + [(UNSPEC_TZCNT "alu1") + (UNSPEC_LZCNT "bitmanip")]) + +;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version +;; provides operand size as output when source operand is zero. + +(define_expand "_" [(parallel [(set (match_operand:SWI248 0 "register_operand") (unspec:SWI248 - [(match_operand:SWI248 1 "nonimmediate_operand")] - UNSPEC_LZCNT)) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_LZCNT") + [(match_operand:SWI248 1 "nonimmediate_operand")] LT_ZCNT)) + (clobber (reg:CC FLAGS_REG))])]) ; False dependency happens when destination is only updated by tzcnt, ; lzcnt or popcnt. There is no false dependency when destination is ; also used in source. -(define_insn_and_split "*lzcnt__falsedep_1" +(define_insn_and_split "*__falsedep_1" [(set (match_operand:SWI48 0 "register_operand" "=r") (unspec:SWI48 - [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] - UNSPEC_LZCNT)) + [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) (clobber (reg:CC FLAGS_REG))] - "TARGET_LZCNT - && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" + "TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" "#" "&& reload_completed" [(parallel [(set (match_dup 0) - (unspec:SWI48 [(match_dup 1)] UNSPEC_LZCNT)) + (unspec:SWI48 [(match_dup 1)] LT_ZCNT)) (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) (clobber (reg:CC FLAGS_REG))])] { @@ -12884,30 +12896,28 @@ ix86_expand_clear (operands[0]); }) -(define_insn "*lzcnt__falsedep" +(define_insn "*__falsedep" [(set (match_operand:SWI48 0 "register_operand" "=r") (unspec:SWI48 - [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] - UNSPEC_LZCNT)) + [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) (unspec [(match_operand:SWI48 2 "register_operand" "0")] UNSPEC_INSN_FALSE_DEP) (clobber (reg:CC FLAGS_REG))] - "TARGET_LZCNT" - "lzcnt{}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") + "" + "{}\t{%1, %0|%0, %1}" + [(set_attr "type" "") (set_attr "prefix_0f" "1") (set_attr "prefix_rep" "1") (set_attr "mode" "")]) -(define_insn "*lzcnt_" +(define_insn "*_" [(set (match_operand:SWI248 0 "register_operand" "=r") (unspec:SWI248 - [(match_operand:SWI248 1 "nonimmediate_operand" "rm")] - UNSPEC_LZCNT)) + [(match_operand:SWI248 1 "nonimmediate_operand" "rm")] LT_ZCNT)) (clobber (reg:CC FLAGS_REG))] - "TARGET_LZCNT" - "lzcnt{}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") + "" + "{}\t{%1, %0|%0, %1}" + [(set_attr "type" "") (set_attr "prefix_0f" "1") (set_attr "prefix_rep" "1") (set_attr "mode" "")]) @@ -13206,42 +13216,6 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "")]) -(define_insn "bsr_rex64" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (const_int 63) - (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT" - "bsr{q}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "znver1_decode" "vector") - (set_attr "mode" "DI")]) - -(define_insn "bsr" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (const_int 31) - (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) - (clobber (reg:CC FLAGS_REG))] - "" - "bsr{l}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "znver1_decode" "vector") - (set_attr "mode" "SI")]) - -(define_insn "*bsrhi" - [(set (match_operand:HI 0 "register_operand" "=r") - (minus:HI (const_int 15) - (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) - (clobber (reg:CC FLAGS_REG))] - "" - "bsr{w}\t{%1, %0|%0, %1}" - [(set_attr "type" "alu1") - (set_attr "prefix_0f" "1") - (set_attr "znver1_decode" "vector") - (set_attr "mode" "HI")]) - (define_expand "popcount2" [(parallel [(set (match_operand:SWI248 0 "register_operand")