On Thu, Jul 15, 2010 at 2:16 PM, Paolo Bonzini <bonz...@gnu.org> wrote: > On 07/15/2010 09:57 AM, Uros Bizjak wrote: >> >> Hello! >> >> I was playing a bit with TARGET_SHIFT_TRUNCATION_MASK on x86 in the >> hope that redundant masking would get eliminated from: >> >> int test (int a, int c) >> { >> return a<< (c& 0x1f); >> } >> >> The macro was defined as: >> >> +/* Implement TARGET_SHIFT_TRUNCATION_MASK. */ >> +static unsigned HOST_WIDE_INT >> +ix86_shift_truncation_mask (enum machine_mode mode) >> +{ >> + switch (mode) >> + { >> + case QImode: >> + case HImode: >> + case SImode: >> + return 31; >> + >> + case DImode: >> + if (TARGET_64BIT) >> + return 63; >> + >> + default: >> + return 0; >> + } >> +} >> >> However, I was not able to get rid of the masking "and". > > FWIW, the reason the hook is not implemented on x86 is that some variants of > bsf/bsr (I think with memory source) do not honor the truncation.
The reason you pointed out is for SHIFT_COUNT_TRUNCATED. Please note, that we don't use memory_operands, but even in register operand case, "bt" insn doesn't truncate the bit-count operand, but performs modulo operation on it. I.E, "bt %reg, 75" will not return 0, but shift insn with the same operands will. Uros.