Hello! Attached patch fixes non-BMI2 shift define-and-split instructions that remove unnecessary masking of count operand by adding a register constraints that allows only CX hard register.
2017-12-21 Uros Bizjak <ubiz...@gmail.com> PR target/83467 * config/i386/i386.md (*ashl<mode>3_mask): Add operand constraints to operand 2. (*ashl<mode>3_mask_1): Ditto. (*<shift_insn><mode>3_mask): Ditto. (*<shift_insn><mode>3_mask_1): Ditto. (*<rotate_insn><mode>3_mask): Ditto. (*<rotate_insn><mode>3_mask_1): Ditto. testsuite/ChangeLog: 2017-12-21 Uros Bizjak <ubiz...@gmail.com> PR target/83467 * gcc.target/i386/pr83467-1.c: New test. * gcc.target/i386/pr83467-2.c: Ditto. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN, will be backported to gcc-7 branch. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 255943) +++ config/i386/i386.md (working copy) @@ -10353,7 +10353,7 @@ (match_operand:SWI48 1 "nonimmediate_operand") (subreg:QI (and:SI - (match_operand:SI 2 "register_operand") + (match_operand:SI 2 "register_operand" "c,r") (match_operand:SI 3 "const_int_operand")) 0))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) @@ -10367,7 +10367,8 @@ (ashift:SWI48 (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[2] = gen_lowpart (QImode, operands[2]);") + "operands[2] = gen_lowpart (QImode, operands[2]);" + [(set_attr "isa" "*,bmi2")]) (define_insn_and_split "*ashl<mode>3_mask_1" [(set (match_operand:SWI48 0 "nonimmediate_operand") @@ -10374,7 +10375,7 @@ (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") (and:QI - (match_operand:QI 2 "register_operand") + (match_operand:QI 2 "register_operand" "c,r") (match_operand:QI 3 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) @@ -10387,7 +10388,9 @@ [(set (match_dup 0) (ashift:SWI48 (match_dup 1) (match_dup 2))) - (clobber (reg:CC FLAGS_REG))])]) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "isa" "*,bmi2")]) (define_insn "*bmi2_ashl<mode>3_1" [(set (match_operand:SWI48 0 "register_operand" "=r") @@ -10873,7 +10876,7 @@ (match_operand:SWI48 1 "nonimmediate_operand") (subreg:QI (and:SI - (match_operand:SI 2 "register_operand") + (match_operand:SI 2 "register_operand" "c,r") (match_operand:SI 3 "const_int_operand")) 0))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) @@ -10887,7 +10890,8 @@ (any_shiftrt:SWI48 (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[2] = gen_lowpart (QImode, operands[2]);") + "operands[2] = gen_lowpart (QImode, operands[2]);" + [(set_attr "isa" "*,bmi2")]) (define_insn_and_split "*<shift_insn><mode>3_mask_1" [(set (match_operand:SWI48 0 "nonimmediate_operand") @@ -10894,7 +10898,7 @@ (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") (and:QI - (match_operand:QI 2 "register_operand") + (match_operand:QI 2 "register_operand" "c,r") (match_operand:QI 3 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) @@ -10907,7 +10911,9 @@ [(set (match_dup 0) (any_shiftrt:SWI48 (match_dup 1) (match_dup 2))) - (clobber (reg:CC FLAGS_REG))])]) + (clobber (reg:CC FLAGS_REG))])] + "" + [(set_attr "isa" "*,bmi2")]) (define_insn_and_split "*<shift_insn><mode>3_doubleword" [(set (match_operand:DWI 0 "register_operand" "=&r") @@ -11352,7 +11358,7 @@ (match_operand:SWI48 1 "nonimmediate_operand") (subreg:QI (and:SI - (match_operand:SI 2 "register_operand") + (match_operand:SI 2 "register_operand" "c") (match_operand:SI 3 "const_int_operand")) 0))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) @@ -11373,7 +11379,7 @@ (any_rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") (and:QI - (match_operand:QI 2 "register_operand") + (match_operand:QI 2 "register_operand" "c") (match_operand:QI 3 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) Index: testsuite/gcc.target/i386/pr83467-1.c =================================================================== --- testsuite/gcc.target/i386/pr83467-1.c (nonexistent) +++ testsuite/gcc.target/i386/pr83467-1.c (working copy) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -flive-range-shrinkage -m8bit-idiv" } */ +/* { dg-require-effective-target int128 } */ + +unsigned a; + +__int128 +b (unsigned c, short d, int e, long f, unsigned __int128 g, char h, + int i, __int128 j) +{ + j %= 5; + c *= i; + e = e >> (g & 31); + h &= e /= d; + g <<= 0 <= 0; + g &= h < j; + return c + d + f + g + h + i + a + j; +} Index: testsuite/gcc.target/i386/pr83467-2.c =================================================================== --- testsuite/gcc.target/i386/pr83467-2.c (nonexistent) +++ testsuite/gcc.target/i386/pr83467-2.c (working copy) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -flive-range-shrinkage" } */ +/* { dg-require-effective-target int128 } */ + +int +a (int b, short c, int d, long e, __int128 f, short g, long h, __int128 i) +{ + d <<= f & 31; + f >>= 127; + g *= d > c; + f >>= g; + return b + e + f + h + i; +}