On 08/28/2013 11:38 AM, Kirill Yukhin wrote: >> When combine puts the AND and the NOT together, we don't know what registers >> we >> want the data in. If we do not supply the general register alternative, with >> the clobber, then we will be FORCED to implement the operation in the mask >> registers, even if this operation had nothing to do with actual vector masks. >> And it ought to come as no surprise that X & ~Y is a fairly common operation. > I agree with all of that. But why to put in BMI alternative as well? Without > it > me may have this pattern w/o clobber and add it when doing split for GPR > constraint.
Uh, no, you can't just add it when doing the split. You could be adding it in a place that the flags register is live. You must ALWAYS have the clobber on the whole pattern when gprs are possible. > @@ -4219,8 +4225,13 @@ ix86_conditional_register_usage (void) > > /* If AVX512F is disabled, squash the registers. */ > if (! TARGET_AVX512F) > + { > for (i = FIRST_EXT_REX_SSE_REG; i < LAST_EXT_REX_SSE_REG; i++) > fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; > + > + for (i = FIRST_MASK_REG; i < LAST_MASK_REG; i++) > + fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; > + } Fix the indentation. > @@ -1429,7 +1450,7 @@ enum reg_class > > /* Get_secondary_mem widens integral modes to BITS_PER_WORD. > There is no need to emit full 64 bit move on 64 bit targets > - for integral modes that can be moved using 32 bit move. */ > + for integral modes that can be moved using 8 bit move. */ > #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \ > ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ Spurious comment change. > +(define_insn "kandn<mode>" > + [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k") > + (and:SWI12 > + (not:SWI12 > + (match_operand:SWI12 1 "register_operand" "r,0,k")) > + (match_operand:SWI12 2 "register_operand" "r,r,k"))) > + (clobber (reg:CC FLAGS_REG))] Yk not k? > +(define_insn "kxnor<mode>" > + [(set (match_operand:SWI12 0 "register_operand" "=r,!k") > + (not:SWI12 > + (xor:SWI12 > + (match_operand:SWI12 1 "register_operand" "0,k") > + (match_operand:SWI12 2 "register_operand" "r,k"))))] > + "TARGET_AVX512F" > + "@ > + # > + kxnorw\t{%2, %1, %0|%0, %1, %2}" > + [(set_attr "type" "*,msklog") > + (set_attr "prefix" "*,vex") > + (set_attr "mode" "<MODE>")]) Likewise. > +(define_split > + [(set (match_operand:SWI12 0 "register_operand") > + (not:SWI12 > + (xor:SWI12 > + (match_dup 0) > + (match_operand:SWI12 1 "register_operand"))))] > + "TARGET_AVX512F && !ANY_MASK_REG_P (operands [0])" > + [(parallel [(set (match_dup 0) > + (xor:HI (match_dup 0) > + (match_dup 1))) > + (clobber (reg:CC FLAGS_REG))]) > + (set (match_dup 0) > + (not:HI (match_dup 0)))] > + "") general_reg_operand. > +(define_insn "kortestzhi" > + [(set (reg:CCZ FLAGS_REG) > + (compare:CCZ > + (ior:HI > + (match_operand:HI 0 "register_operand" "%Yk") > + (match_operand:HI 1 "register_operand" "Yk")) Omit the %; the two operands are identical. > +(define_insn "kortestchi" > + [(set (reg:CCC FLAGS_REG) > + (compare:CCC > + (ior:HI > + (match_operand:HI 0 "register_operand" "%Yk") > + (match_operand:HI 1 "register_operand" "Yk")) Likewise. > +;; Do not split instructions with mask regs. > (define_split > [(set (match_operand 0 "register_operand") > (not (match_operand 1 "register_operand")))] > @@ -16486,7 +16683,9 @@ > && (GET_MODE (operands[0]) == HImode > || (GET_MODE (operands[0]) == QImode > && (TARGET_PROMOTE_QImode > - || optimize_insn_for_size_p ())))" > + || optimize_insn_for_size_p ()))) > + && (! ANY_MASK_REG_P (operands[0]) > + || ! ANY_MASK_REG_P (operands[1]))" > [(set (match_dup 0) > (not:SI (match_dup 1)))] general_reg_operand. r~