Hello! Attached patch tightens rorx operand 2 predicate to allow only const_int RTXes that are also allowed by the operand constraint. This prevents combine to propagate unsupported const_ints to the pattern.
2017-07-18 Uros Bizjak <ubiz...@gmail.com> PR target/81471 * config/i386/i386.md (rorx_immediate_operand): New mode attribute. (*bmi2_rorx<mode>3_1): Use rorx_immediate_operand as operand 2 predicate. (*bmi2_rorxsi3_1_zext): Use const_0_to_31_operand as operand 2 predicate. (ror,rol -> rorx splitters): Use const_int_operand as operand 2 predicate. testsuite/ChangeLog: 2017-07-18 Uros Bizjak <ubiz...@gmail.com> PR target/81471 * gcc.target/i386/pr81471.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN, will be backported to other release branches. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 250278) +++ config/i386/i386.md (working copy) @@ -10732,10 +10732,15 @@ split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); }) +(define_mode_attr rorx_immediate_operand + [(SI "const_0_to_31_operand") + (DI "const_0_to_63_operand")]) + (define_insn "*bmi2_rorx<mode>3_1" [(set (match_operand:SWI48 0 "register_operand" "=r") - (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (match_operand:QI 2 "immediate_operand" "<S>")))] + (rotatert:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))] "TARGET_BMI2" "rorx\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "rotatex") @@ -10778,7 +10783,7 @@ (define_split [(set (match_operand:SWI48 0 "register_operand") (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") - (match_operand:QI 2 "immediate_operand"))) + (match_operand:QI 2 "const_int_operand"))) (clobber (reg:CC FLAGS_REG))] "TARGET_BMI2 && reload_completed" [(set (match_dup 0) @@ -10792,7 +10797,7 @@ (define_split [(set (match_operand:SWI48 0 "register_operand") (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") - (match_operand:QI 2 "immediate_operand"))) + (match_operand:QI 2 "const_int_operand"))) (clobber (reg:CC FLAGS_REG))] "TARGET_BMI2 && reload_completed" [(set (match_dup 0) @@ -10802,7 +10807,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") - (match_operand:QI 2 "immediate_operand" "I"))))] + (match_operand:QI 2 "const_0_to_31_operand" "I"))))] "TARGET_64BIT && TARGET_BMI2" "rorx\t{%2, %1, %k0|%k0, %1, %2}" [(set_attr "type" "rotatex") @@ -10846,7 +10851,7 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (rotate:SI (match_operand:SI 1 "nonimmediate_operand") - (match_operand:QI 2 "immediate_operand")))) + (match_operand:QI 2 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && TARGET_BMI2 && reload_completed" [(set (match_dup 0) @@ -10861,7 +10866,7 @@ [(set (match_operand:DI 0 "register_operand") (zero_extend:DI (rotatert:SI (match_operand:SI 1 "nonimmediate_operand") - (match_operand:QI 2 "immediate_operand")))) + (match_operand:QI 2 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && TARGET_BMI2 && reload_completed" [(set (match_dup 0) Index: testsuite/gcc.target/i386/pr81471.c =================================================================== --- testsuite/gcc.target/i386/pr81471.c (nonexistent) +++ testsuite/gcc.target/i386/pr81471.c (working copy) @@ -0,0 +1,13 @@ +/* PR target/81471 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mbmi2" } */ + +static inline unsigned int rotl (unsigned int x, int k) +{ + return (x << k) | (x >> (32 - k)); +} + +unsigned long long test (unsigned int z) +{ + return rotl (z, 55); +}