I am not familiar how to use define_subst, so I write a patch that changes define_insn_and_split to define_insn. bootstrapped and regression tested on x86_64-unknown-linux-gnu.
A question is: after that change, Is there anyway I can make targetm.rtx_costs() aware about the truncation, .i.e the cost is only a "shift" instead of "shift + and". Thanks, Wei. On Tue, Mar 26, 2013 at 11:23 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Tue, Mar 26, 2013 at 10:14 AM, Richard Biener > <richard.guent...@gmail.com> wrote: >>>> I am trying to figure out a way not to lose the opportunity when shift >>>> truncation is not combined in a bit test pattern. Can we keep the >>>> explicit truncation in RTL, but generate truncation code in assembly? >>>> Then only shift truncation which not combined in a bit test >>>> pattershift truncationn will happen. >>>> >>>> (define_insn "*<shift_insn_and><mode>" >>>> [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") >>>> (any_shiftrt:SWI48 >>>> (match_operand:SWI48 1 "nonimmediate_operand" "0") >>>> (subreg:QI >>>> (and:SI >>>> (match_operand:SI 2 "nonimmediate_operand" "c") >>>> (match_operand:SI 3 "const_int_operand" "n")) 0))) >>>> (clobber (reg:CC FLAGS_REG))] >>>> "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" >>>> { >>>> if ((INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) >>>> == GET_MODE_BITSIZE (<MODE>mode)-1) >>>> return "and\t{%3, %2|%2, %3}\n\r shift\t{%b2, %0|%0, %b2}"; >>>> else >>>> "shift\t{%2, %0|%0, %2}"; >>>> } >>> >>> Sorry, rectify a mistake: >>> >>> { >>> if ((INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) >>> == GET_MODE_BITSIZE (<MODE>mode)-1) >>> return "shift\t{%2, %0|%0, %2}"; >>> else >>> return "and\t{%3, %2|%2, %3}\n\r shift\t{%b2, %0|%0, %b2}"; >>> } >> >> I'm not sure the existing patterns are wrong because SHIFT_COUNT_TRUNCATED >> is false for x86 AFAIK, exactly because of the bit-test vs. shift instruction >> differences. So there is no inconsistency. The i386 backend seems to >> try to follow my suggestion as if SHIFT_COUNT_TRUNCATED didn't exist >> (well, it's false, so it technically doesn't exist for i386) and recognizes >> the shift with truncate with the *<shift_insn><mode>3_mask splitter. >> But I'm not sure why it bothers to do it with a splitter instead of just >> with a define_insn? Because the split code, >> >> [(parallel [(set (match_dup 0) >> (any_shiftrt:SWI48 (match_dup 1) (match_dup 2))) >> (clobber (reg:CC FLAGS_REG))])] >> >> is wrong and could be combined into a bit-test instruction. No? >> >> That is, why not have define_insn variants for shift instructions with >> explicit truncation? > > You are right, the split is harmful in this case. > > It looks to me, that explicit truncation can be added to split > patterns in the most elegant way using proposed "define_subst" > infrastructure. > > Uros.
changelog
Description: Binary data
patch
Description: Binary data