On Fri, Dec 2, 2016 at 5:11 PM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Fri, Dec 2, 2016 at 3:21 PM, Jakub Jelinek <ja...@redhat.com> wrote: >> Hi! >> >> While the https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01087.html >> added *andndi3_doubleword, I don't understand how it can actually work. >> The problem is that this pattern is for combine, and needs combining >> of DImode NOT setter with DImode AND user. But there is no DImode >> pattern for one_cmpldi2, so it is lowered early into two one_cmplsi2 >> patterns and I can't see how combine would be able to figure stuff out from >> that. >> >> This patch: >> 1) adds one_cmpldi2 pattern for stv purposes (which splits into two >> one_cmplsi2 after reload) >> 2) teaches the 32-bit stv pass to handle NOT (as xor all-ones) >> 3) renames the old *andndi3_doubleword to *andndi3_doubleword_bmi, as it >> is for -mbmi only, and adds another *andndi3_doubleword pattern that is >> meant to live just from combine till the stv pass, or worse case till >> following split1 pass when it is split back into not followed by and; >> this change makes it possible to use pandn in stv pass, even without >> -mbmi > > Please use attached (lightly tested) patch to implement point 3) > above. The patch splits insn after reload, as is the case with all STV > patterns.
Now attached for real. Uros.
Index: i386.md =================================================================== --- i386.md (revision 243185) +++ i386.md (working copy) @@ -8534,15 +8534,24 @@ operands[2] = gen_lowpart (QImode, operands[2]); }) -(define_insn_and_split "*andndi3_doubleword" - [(set (match_operand:DI 0 "register_operand" "=r") +(define_insn "*andndi3_doubleword" + [(set (match_operand:DI 0 "register_operand" "=r,&r") (and:DI - (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "nonimmediate_operand" "rm"))) + (not:DI (match_operand:DI 1 "register_operand" "r,0")) + (match_operand:DI 2 "nonimmediate_operand" "rm,rm"))) (clobber (reg:CC FLAGS_REG))] - "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE2" + "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" "#" - "&& reload_completed" + [(set_attr "isa" "bmi,*")]) + +(define_split + [(set (match_operand:DI 0 "register_operand") + (and:DI + (not:DI (match_operand:DI 1 "register_operand")) + (match_operand:DI 2 "nonimmediate_operand"))) + (clobber (reg:CC FLAGS_REG))] + "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2 + && reload_completed" [(parallel [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) (clobber (reg:CC FLAGS_REG))]) @@ -8551,6 +8560,24 @@ (clobber (reg:CC FLAGS_REG))])] "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);") +(define_split + [(set (match_operand:DI 0 "register_operand") + (and:DI + (not:DI (match_dup 0)) + (match_operand:DI 1 "nonimmediate_operand"))) + (clobber (reg:CC FLAGS_REG))] + "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2 + && reload_completed" + [(set (match_dup 0) (not:SI (match_dup 0))) + (parallel [(set (match_dup 0) + (and:SI (match_dup 0) (match_dup 1))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 2) (not:SI (match_dup 2))) + (parallel [(set (match_dup 2) + (and:SI (match_dup 2) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))])] + "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") + (define_insn "*andn<mode>_1" [(set (match_operand:SWI48 0 "register_operand" "=r,r") (and:SWI48