(ashift:<DWI>
(match_operand:<DWI> 1 "register_operand")
(subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c")
- (match_operand:SI 3 "const_int_operand")) 0)))
- (clobber (reg:CC FLAGS_REG))]
- "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ (and
+ (match_operand 2 "register_operand" "c")
+ (match_operand 3 "const_int_operand")) 0)))
+ (clobber (reg:CC FLAGS_REG))]
+ "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
+ == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(ashift:DWIH (match_dup 5) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
{
+ if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
+ {
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+ operands[2] = gen_lowpart (QImode, operands[2]);
+ emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+
split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
operands[2] = tem;
}
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
operands[2] = gen_lowpart (QImode, operands[2]);
if (!rtx_equal_p (operands[6], operands[7]))
(match_operand:QI 2 "register_operand" "c")
(match_operand:QI 3 "const_int_operand"))))
(clobber (reg:CC FLAGS_REG))]
- "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
+ == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(ashift:DWIH (match_dup 5) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
{
+ if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
+ {
+ emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+
split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
emit_move_insn (operands[6], operands[7]);
})
-(define_insn "*ashl<mode>3_doubleword"
+(define_insn "ashl<mode>3_doubleword"
[(set (match_operand:DWI 0 "register_operand" "=&r")
(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
(match_operand:QI 2 "nonmemory_operand" "<S>c")))
(ashift:SWI48
(match_operand:SWI48 1 "nonimmediate_operand")
(subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c,r")
- (match_operand:SI 3 "const_int_operand")) 0)))
+ (and
+ (match_operand 2 "register_operand" "c,r")
+ (match_operand 3 "const_int_operand")) 0)))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
&& (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
== GET_MODE_BITSIZE (<MODE>mode)-1
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(ashift:SWI48 (match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
- "operands[2] = gen_lowpart (QImode, operands[2]);"
+{
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+ operands[2] = gen_lowpart (QImode, operands[2]);
+}
[(set_attr "isa" "*,bmi2")])
(define_insn_and_split "*ashl<mode>3_mask_1"
(any_shiftrt:SWI48
(match_operand:SWI48 1 "nonimmediate_operand")
(subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c,r")
- (match_operand:SI 3 "const_int_operand")) 0)))
+ (and
+ (match_operand 2 "register_operand" "c,r")
+ (match_operand 3 "const_int_operand")) 0)))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
&& (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
== GET_MODE_BITSIZE (<MODE>mode)-1
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(any_shiftrt:SWI48 (match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
- "operands[2] = gen_lowpart (QImode, operands[2]);"
+{
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+ operands[2] = gen_lowpart (QImode, operands[2]);
+}
[(set_attr "isa" "*,bmi2")])
(define_insn_and_split "*<insn><mode>3_mask_1"
(any_shiftrt:<DWI>
(match_operand:<DWI> 1 "register_operand")
(subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c")
- (match_operand:SI 3 "const_int_operand")) 0)))
- (clobber (reg:CC FLAGS_REG))]
- "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ (and
+ (match_operand 2 "register_operand" "c")
+ (match_operand 3 "const_int_operand")) 0)))
+ (clobber (reg:CC FLAGS_REG))]
+ "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
+ == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
{
+ if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
+ {
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+ operands[2] = gen_lowpart (QImode, operands[2]);
+ emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+
split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
operands[2] = tem;
}
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
operands[2] = gen_lowpart (QImode, operands[2]);
if (!rtx_equal_p (operands[4], operands[5]))
(match_operand:QI 2 "register_operand" "c")
(match_operand:QI 3 "const_int_operand"))))
(clobber (reg:CC FLAGS_REG))]
- "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
+ || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
+ == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
{
+ if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
+ {
+ emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
+ operands[2]));
+ DONE;
+ }
+
split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
emit_move_insn (operands[4], operands[5]);
})
-(define_insn_and_split "*<insn><mode>3_doubleword"
+(define_insn_and_split "<insn><mode>3_doubleword"
[(set (match_operand:DWI 0 "register_operand" "=&r")
(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "<S>c")))
(any_rotate:SWI
(match_operand:SWI 1 "nonimmediate_operand")
(subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c")
- (match_operand:SI 3 "const_int_operand")) 0)))
+ (and
+ (match_operand 2 "register_operand" "c")
+ (match_operand 3 "const_int_operand")) 0)))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
&& (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
== GET_MODE_BITSIZE (<MODE>mode)-1
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(any_rotate:SWI (match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
- "operands[2] = gen_lowpart (QImode, operands[2]);")
+{
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+ operands[2] = gen_lowpart (QImode, operands[2]);
+})
(define_split
[(set (match_operand:SWI 0 "register_operand")
(any_rotate:SWI
(match_operand:SWI 1 "const_int_operand")
(subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "const_int_operand")) 0)))]
+ (and
+ (match_operand 2 "register_operand")
+ (match_operand 3 "const_int_operand")) 0)))]
"(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
- == GET_MODE_BITSIZE (<MODE>mode) - 1"
+ == GET_MODE_BITSIZE (<MODE>mode) - 1
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))"
[(set (match_dup 4) (match_dup 1))
(set (match_dup 0)
(any_rotate:SWI (match_dup 4)
(ashift:SWI48
(const_int 1)
(subreg:QI
- (and:SI
- (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "const_int_operand")) 0))
+ (and
+ (match_operand 1 "register_operand")
+ (match_operand 2 "const_int_operand")) 0))
(match_operand:SWI48 3 "register_operand")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_USE_BT
&& (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
== GET_MODE_BITSIZE (<MODE>mode)-1
+ && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[1])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(match_dup 1))
(match_dup 3)))
(clobber (reg:CC FLAGS_REG))])]
- "operands[1] = gen_lowpart (QImode, operands[1]);")
+{
+ operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
+ operands[1] = gen_lowpart (QImode, operands[1]);
+})
(define_insn_and_split "*<btsc><mode>_mask_1"
[(set (match_operand:SWI48 0 "register_operand")
(rotate:SWI48
(const_int -2)
(subreg:QI
- (and:SI
- (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "const_int_operand")) 0))
+ (and
+ (match_operand 1 "register_operand")
+ (match_operand 2 "const_int_operand")) 0))
(match_operand:SWI48 3 "register_operand")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_USE_BT
&& (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
== GET_MODE_BITSIZE (<MODE>mode)-1
+ && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[1])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
&& ix86_pre_reload_split ()"
"#"
"&& 1"
(match_dup 1))
(match_dup 3)))
(clobber (reg:CC FLAGS_REG))])]
- "operands[1] = gen_lowpart (QImode, operands[1]);")
+{
+ operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
+ operands[1] = gen_lowpart (QImode, operands[1]);
+})
(define_insn_and_split "*btr<mode>_mask_1"
[(set (match_operand:SWI48 0 "register_operand")
PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
})
+(define_insn_and_split "*jcc_bt<mode>_mask_1"
+ [(set (pc)
+ (if_then_else (match_operator 0 "bt_comparison_operator"
+ [(zero_extract:SWI48
+ (match_operand:SWI48 1 "register_operand")
+ (const_int 1)
+ (zero_extend:SI
+ (subreg:QI
+ (and
+ (match_operand 2 "register_operand")
+ (match_operand 3 "const_int_operand")) 0)))])
+ (label_ref (match_operand 4))
+ (pc)))
+ (clobber (reg:CC FLAGS_REG))]
+ "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
+ && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+ == GET_MODE_BITSIZE (<MODE>mode)-1
+ && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
+ && IN_RANGE (GET_MODE_SIZE (GET_MODE (operands[2])), 2,
+ 4 << (TARGET_64BIT ? 1 : 0))
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (zero_extract:SWI48
+ (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (const_int 0)))
+ (set (pc)
+ (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+ (label_ref (match_dup 4))
+ (pc)))]
+{
+ operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+ operands[2] = gen_lowpart (SImode, operands[2]);
+ operands[0] = shallow_copy_rtx (operands[0]);
+ PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
+})
+
;; Help combine recognize bt followed by cmov
(define_split
[(set (match_operand:SWI248 0 "register_operand")
--- /dev/null
+/* PR target/105778 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "\tand\[^\n\r]*\(31\|63\|127\|255\)" } } */
+
+unsigned int f1 (unsigned int x, unsigned long y) { y &= 31; return x << y; }
+unsigned int f2 (unsigned int x, unsigned long y) { return x << (y & 31); }
+unsigned int f3 (unsigned int x, unsigned long y) { y &= 31; return x >> y; }
+unsigned int f4 (unsigned int x, unsigned long y) { return x >> (y & 31); }
+int f5 (int x, unsigned long y) { y &= 31; return x >> y; }
+int f6 (int x, unsigned long y) { return x >> (y & 31); }
+unsigned long long f7 (unsigned long long x, unsigned long y) { y &= 63; return x << y; }
+unsigned long long f8 (unsigned long long x, unsigned long y) { return x << (y & 63); }
+unsigned long long f9 (unsigned long long x, unsigned long y) { y &= 63; return x >> y; }
+unsigned long long f10 (unsigned long long x, unsigned long y) { return x >> (y & 63); }
+long long f11 (long long x, unsigned long y) { y &= 63; return x >> y; }
+long long f12 (long long x, unsigned long y) { return x >> (y & 63); }
+#ifdef __SIZEOF_INT128__
+unsigned __int128 f13 (unsigned __int128 x, unsigned long y) { y &= 127; return x << y; }
+unsigned __int128 f14 (unsigned __int128 x, unsigned long y) { return x << (y & 127); }
+unsigned __int128 f15 (unsigned __int128 x, unsigned long y) { y &= 127; return x >> y; }
+unsigned __int128 f16 (unsigned __int128 x, unsigned long y) { return x >> (y & 127); }
+__int128 f17 (__int128 x, unsigned long y) { y &= 127; return x >> y; }
+__int128 f18 (__int128 x, unsigned long y) { return x >> (y & 127); }
+#endif
+unsigned int f19 (unsigned int x, unsigned long y) { y &= 63; return x << y; }
+unsigned int f20 (unsigned int x, unsigned long y) { return x << (y & 63); }
+unsigned int f21 (unsigned int x, unsigned long y) { y &= 63; return x >> y; }
+unsigned int f22 (unsigned int x, unsigned long y) { return x >> (y & 63); }
+int f23 (int x, unsigned long y) { y &= 63; return x >> y; }
+int f24 (int x, unsigned long y) { return x >> (y & 63); }
+unsigned long long f25 (unsigned long long x, unsigned long y) { y &= 127; return x << y; }
+unsigned long long f26 (unsigned long long x, unsigned long y) { return x << (y & 127); }
+unsigned long long f27 (unsigned long long x, unsigned long y) { y &= 127; return x >> y; }
+unsigned long long f28 (unsigned long long x, unsigned long y) { return x >> (y & 127); }
+long long f29 (long long x, unsigned long y) { y &= 127; return x >> y; }
+long long f30 (long long x, unsigned long y) { return x >> (y & 127); }
+#ifdef __SIZEOF_INT128__
+unsigned __int128 f31 (unsigned __int128 x, unsigned long y) { y &= 255; return x << y; }
+unsigned __int128 f32 (unsigned __int128 x, unsigned long y) { return x << (y & 255); }
+unsigned __int128 f33 (unsigned __int128 x, unsigned long y) { y &= 255; return x >> y; }
+unsigned __int128 f34 (unsigned __int128 x, unsigned long y) { return x >> (y & 255); }
+__int128 f35 (__int128 x, unsigned long y) { y &= 255; return x >> y; }
+__int128 f36 (__int128 x, unsigned long y) { return x >> (y & 255); }
+#endif