diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 68606e57e6092079058048121ba8ad7f136eb15a..24368c73edca8554b1fd57398f11e232938c6999 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11301,9 +11301,12 @@ "&& 1" [(parallel [(set (match_dup 6) - (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2)) - (lshiftrt:DWIH (match_dup 5) - (minus:QI (match_dup 8) (match_dup 2))))) + (ior:DWIH (ashift:DWIH (match_dup 6) + (and:QI (match_dup 2) (match_dup 8))) + (subreg:DWIH + (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5)) + (minus:QI (match_dup 9) + (and:QI (match_dup 2) (match_dup 8)))) 0))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 4) @@ -11312,7 +11315,8 @@ { split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); - operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1); + operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) @@ -11342,9 +11346,12 @@ "&& 1" [(parallel [(set (match_dup 6) - (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2)) - (lshiftrt:DWIH (match_dup 5) - (minus:QI (match_dup 8) (match_dup 2))))) + (ior:DWIH (ashift:DWIH (match_dup 6) + (and:QI (match_dup 2) (match_dup 8))) + (subreg:DWIH + (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5)) + (minus:QI (match_dup 9) + (and:QI (match_dup 2) (match_dup 8)))) 0))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 4) @@ -11353,7 +11360,8 @@ { split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); - operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1); + operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) @@ -11404,9 +11412,14 @@ (define_insn "x86_64_shld" [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") (ior:DI (ashift:DI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "Jc")) - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") - (minus:QI (const_int 64) (match_dup 2))))) + (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc") + (const_int 63))) + (subreg:DI + (lshiftrt:TI + (zero_extend:TI + (match_operand:DI 1 "register_operand" "r")) + (minus:QI (const_int 64) + (and:QI (match_dup 2) (const_int 63)))) 0))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "shld{q}\t{%s2%1, %0|%0, %1, %2}" @@ -11417,12 +11430,58 @@ (set_attr "amdfam10_decode" "vector") (set_attr "bdver1_decode" "vector")]) +(define_insn "*x86_64_shld_1" + [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") + (ior:DI (ashift:DI (match_dup 0) + (match_operand:QI 2 "const_0_to_63_operand" "J")) + (subreg:DI + (lshiftrt:TI + (zero_extend:TI + (match_operand:DI 1 "register_operand" "r")) + (match_operand:QI 3 "const_0_to_255_operand" "N")) 0))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && INTVAL (operands[3]) == 64 - INTVAL (operands[2])" + "shld{q}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ishift") + (set_attr "prefix_0f" "1") + (set_attr "mode" "DI") + (set_attr "athlon_decode" "vector") + (set_attr "amdfam10_decode" "vector") + (set_attr "bdver1_decode" "vector")]) + +(define_insn_and_split "*x86_64_shld_2" + [(set (match_operand:DI 0 "nonimmediate_operand") + (ior:DI (ashift:DI (match_dup 0) + (match_operand:QI 2 "nonmemory_operand")) + (lshiftrt:DI (match_operand:DI 1 "register_operand") + (minus:QI (const_int 64) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && ix86_pre_reload_split ()" + "#" + "&& 1" + [(parallel [(set (match_dup 0) + (ior:DI (ashift:DI (match_dup 0) + (and:QI (match_dup 2) (const_int 63))) + (subreg:DI + (lshiftrt:TI + (zero_extend:TI (match_dup 1)) + (minus:QI (const_int 64) + (and:QI (match_dup 2) + (const_int 63)))) 0))) + (clobber (reg:CC FLAGS_REG))])]) + (define_insn "x86_shld" [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") (ior:SI (ashift:SI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "Ic")) - (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") - (minus:QI (const_int 32) (match_dup 2))))) + (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic") + (const_int 31))) + (subreg:SI + (lshiftrt:DI + (zero_extend:DI + (match_operand:SI 1 "register_operand" "r")) + (minus:QI (const_int 32) + (and:QI (match_dup 2) (const_int 31)))) 0))) (clobber (reg:CC FLAGS_REG))] "" "shld{l}\t{%s2%1, %0|%0, %1, %2}" @@ -11434,6 +11493,47 @@ (set_attr "amdfam10_decode" "vector") (set_attr "bdver1_decode" "vector")]) +(define_insn "*x86_shld_1" + [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") + (ior:SI (ashift:SI (match_dup 0) + (match_operand:QI 2 "const_0_to_31_operand" "I")) + (subreg:SI + (lshiftrt:DI + (zero_extend:DI + (match_operand:SI 1 "register_operand" "r")) + (match_operand:QI 3 "const_0_to_63_operand" "J")) 0))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) == 32 - INTVAL (operands[2])" + "shld{l}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ishift") + (set_attr "prefix_0f" "1") + (set_attr "mode" "SI") + (set_attr "pent_pair" "np") + (set_attr "athlon_decode" "vector") + (set_attr "amdfam10_decode" "vector") + (set_attr "bdver1_decode" "vector")]) + +(define_insn_and_split "*x86_shld_2" + [(set (match_operand:SI 0 "nonimmediate_operand") + (ior:SI (ashift:SI (match_dup 0) + (match_operand:QI 2 "nonmemory_operand")) + (lshiftrt:SI (match_operand:SI 1 "register_operand") + (minus:QI (const_int 32) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && ix86_pre_reload_split ()" + "#" + "&& 1" + [(parallel [(set (match_dup 0) + (ior:SI (ashift:SI (match_dup 0) + (and:QI (match_dup 2) (const_int 31))) + (subreg:SI + (lshiftrt:DI + (zero_extend:DI (match_dup 1)) + (minus:QI (const_int 32) + (and:QI (match_dup 2) + (const_int 31)))) 0))) + (clobber (reg:CC FLAGS_REG))])]) + (define_expand "@x86_shift<mode>_adj_1" [(set (reg:CCZ FLAGS_REG) (compare:CCZ (and:QI (match_operand:QI 2 "register_operand") @@ -12080,9 +12180,12 @@ "&& 1" [(parallel [(set (match_dup 4) - (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) - (ashift:DWIH (match_dup 7) - (minus:QI (match_dup 8) (match_dup 2))))) + (ior:DWIH (lshiftrt:DWIH (match_dup 4) + (and:QI (match_dup 2) (match_dup 8))) + (subreg:DWIH + (ashift:<DWI> (zero_extend:<DWI> (match_dup 7)) + (minus:QI (match_dup 9) + (and:QI (match_dup 2) (match_dup 8)))) 0))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 6) @@ -12091,7 +12194,8 @@ { split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); - operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1); + operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) @@ -12121,9 +12225,12 @@ "&& 1" [(parallel [(set (match_dup 4) - (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) - (ashift:DWIH (match_dup 7) - (minus:QI (match_dup 8) (match_dup 2))))) + (ior:DWIH (lshiftrt:DWIH (match_dup 4) + (and:QI (match_dup 2) (match_dup 8))) + (subreg:DWIH + (ashift:<DWI> (zero_extend:<DWI> (match_dup 7)) + (minus:QI (match_dup 9) + (and:QI (match_dup 2) (match_dup 8)))) 0))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 6) @@ -12132,7 +12239,8 @@ { split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); - operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); + operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1); + operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) @@ -12177,9 +12285,14 @@ (define_insn "x86_64_shrd" [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") (ior:DI (lshiftrt:DI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "Jc")) - (ashift:DI (match_operand:DI 1 "register_operand" "r") - (minus:QI (const_int 64) (match_dup 2))))) + (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc") + (const_int 63))) + (subreg:DI + (ashift:TI + (zero_extend:TI + (match_operand:DI 1 "register_operand" "r")) + (minus:QI (const_int 64) + (and:QI (match_dup 2) (const_int 63)))) 0))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT" "shrd{q}\t{%s2%1, %0|%0, %1, %2}" @@ -12190,12 +12303,58 @@ (set_attr "amdfam10_decode" "vector") (set_attr "bdver1_decode" "vector")]) +(define_insn "*x86_64_shrd_1" + [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") + (ior:DI (lshiftrt:DI (match_dup 0) + (match_operand:QI 2 "const_0_to_63_operand" "J")) + (subreg:DI + (ashift:TI + (zero_extend:TI + (match_operand:DI 1 "register_operand" "r")) + (match_operand:QI 3 "const_0_to_255_operand" "N")) 0))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT + && INTVAL (operands[3]) == 64 - INTVAL (operands[2])" + "shrd{q}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ishift") + (set_attr "prefix_0f" "1") + (set_attr "mode" "DI") + (set_attr "athlon_decode" "vector") + (set_attr "amdfam10_decode" "vector") + (set_attr "bdver1_decode" "vector")]) + +(define_insn_and_split "*x86_64_shrd_2" + [(set (match_operand:DI 0 "nonimmediate_operand") + (ior:DI (lshiftrt:DI (match_dup 0) + (match_operand:QI 2 "nonmemory_operand")) + (ashift:DI (match_operand:DI 1 "register_operand") + (minus:QI (const_int 64) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && ix86_pre_reload_split ()" + "#" + "&& 1" + [(parallel [(set (match_dup 0) + (ior:DI (lshiftrt:DI (match_dup 0) + (and:QI (match_dup 2) (const_int 63))) + (subreg:DI + (ashift:TI + (zero_extend:TI (match_dup 1)) + (minus:QI (const_int 64) + (and:QI (match_dup 2) + (const_int 63)))) 0))) + (clobber (reg:CC FLAGS_REG))])]) + (define_insn "x86_shrd" [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") (ior:SI (lshiftrt:SI (match_dup 0) - (match_operand:QI 2 "nonmemory_operand" "Ic")) - (ashift:SI (match_operand:SI 1 "register_operand" "r") - (minus:QI (const_int 32) (match_dup 2))))) + (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic") + (const_int 31))) + (subreg:SI + (ashift:DI + (zero_extend:DI + (match_operand:SI 1 "register_operand" "r")) + (minus:QI (const_int 32) + (and:QI (match_dup 2) (const_int 31)))) 0))) (clobber (reg:CC FLAGS_REG))] "" "shrd{l}\t{%s2%1, %0|%0, %1, %2}" @@ -12207,6 +12366,47 @@ (set_attr "amdfam10_decode" "vector") (set_attr "bdver1_decode" "vector")]) +(define_insn "*x86_shrd_1" + [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") + (ior:SI (lshiftrt:SI (match_dup 0) + (match_operand:QI 2 "const_0_to_31_operand" "I")) + (subreg:SI + (ashift:DI + (zero_extend:DI + (match_operand:SI 1 "register_operand" "r")) + (match_operand:QI 3 "const_0_to_63_operand" "J")) 0))) + (clobber (reg:CC FLAGS_REG))] + "INTVAL (operands[3]) == 32 - INTVAL (operands[2])" + "shrd{l}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "ishift") + (set_attr "prefix_0f" "1") + (set_attr "mode" "SI") + (set_attr "pent_pair" "np") + (set_attr "athlon_decode" "vector") + (set_attr "amdfam10_decode" "vector") + (set_attr "bdver1_decode" "vector")]) + +(define_insn_and_split "*x86_shrd_2" + [(set (match_operand:SI 0 "nonimmediate_operand") + (ior:SI (lshiftrt:SI (match_dup 0) + (match_operand:QI 2 "nonmemory_operand")) + (ashift:SI (match_operand:SI 1 "register_operand") + (minus:QI (const_int 32) (match_dup 2))))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_64BIT && ix86_pre_reload_split ()" + "#" + "&& 1" + [(parallel [(set (match_dup 0) + (ior:SI (lshiftrt:SI (match_dup 0) + (and:QI (match_dup 2) (const_int 31))) + (subreg:SI + (ashift:DI + (zero_extend:DI (match_dup 1)) + (minus:QI (const_int 32) + (and:QI (match_dup 2) + (const_int 31)))) 0))) + (clobber (reg:CC FLAGS_REG))])]) + ;; Base name for insn mnemonic. (define_mode_attr cvt_mnemonic [(SI "{cltd|cdq}") (DI "{cqto|cqo}")]) @@ -12784,18 +12984,27 @@ [(set (match_dup 3) (match_dup 4)) (parallel [(set (match_dup 4) - (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) - (lshiftrt:DWIH (match_dup 5) - (minus:QI (match_dup 6) (match_dup 2))))) + (ior:DWIH (ashift:DWIH (match_dup 4) + (and:QI (match_dup 2) (match_dup 6))) + (subreg:DWIH + (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5)) + (minus:QI (match_dup 7) + (and:QI (match_dup 2) + (match_dup 6)))) 0))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 5) - (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) - (lshiftrt:DWIH (match_dup 3) - (minus:QI (match_dup 6) (match_dup 2))))) + (ior:DWIH (ashift:DWIH (match_dup 5) + (and:QI (match_dup 2) (match_dup 6))) + (subreg:DWIH + (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3)) + (minus:QI (match_dup 7) + (and:QI (match_dup 2) + (match_dup 6)))) 0))) (clobber (reg:CC FLAGS_REG))])] { - operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); + operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); + operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); }) @@ -12812,18 +13021,27 @@ [(set (match_dup 3) (match_dup 4)) (parallel [(set (match_dup 4) - (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) - (ashift:DWIH (match_dup 5) - (minus:QI (match_dup 6) (match_dup 2))))) + (ior:DWIH (lshiftrt:DWIH (match_dup 4) + (and:QI (match_dup 2) (match_dup 6))) + (subreg:DWIH + (ashift:<DWI> (zero_extend:<DWI> (match_dup 5)) + (minus:QI (match_dup 7) + (and:QI (match_dup 2) + (match_dup 6)))) 0))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 5) - (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2)) - (ashift:DWIH (match_dup 3) - (minus:QI (match_dup 6) (match_dup 2))))) + (ior:DWIH (lshiftrt:DWIH (match_dup 5) + (and:QI (match_dup 2) (match_dup 6))) + (subreg:DWIH + (ashift:<DWI> (zero_extend:<DWI> (match_dup 3)) + (minus:QI (match_dup 7) + (and:QI (match_dup 2) + (match_dup 6)))) 0))) (clobber (reg:CC FLAGS_REG))])] { - operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); + operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); + operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); }) diff --git a/gcc/testsuite/gcc.dg/pr103431.c b/gcc/testsuite/gcc.dg/pr103431.c new file mode 100644 index 0000000000000000000000000000000000000000..09f224a3903758f940eae5789937df754d2e15d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103431.c @@ -0,0 +1,21 @@ +/* PR middle-end/103431 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O -fno-tree-bit-ccp -fno-tree-dominator-opts" } */ + +__attribute__((noipa)) +void foo (unsigned short a) +{ + __uint128_t b = 5; + int size = __SIZEOF_INT128__ * __CHAR_BIT__ - 1; + a /= 0xfffffffd; + __uint128_t c = (b << (a & size) | b >> (-(a & size) & size)); + if (c != 5) + __builtin_abort (); +} + +int +main () +{ + foo (0); + return 0; +}