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

Reply via email to