On Wed, Nov 13, 2024 at 09:22:45AM +0100, Richard Biener wrote:
> While I'm far from an expert here this doesn't look right and instead the
> const_0_to_255_operand looks bogus to me in not properly taking into
> account 'mode'.

I think the bug is in use of const_0_to_255* predicates with QImode or
mode-less operands, i.e.
grep const_0_to_255 *.md | grep -v ':SI\|define_predicate'
i386.md:                    (match_operand:QI 3 "const_0_to_255_operand")) 0)))]
i386.md:                    (match_operand:QI 4 "const_0_to_255_operand")) 0)))]
i386.md:                    (match_operand:QI 3 "const_0_to_255_operand")) 0)))]
i386.md:                    (match_operand:QI 4 "const_0_to_255_operand")) 0)))]
i386.md:          (match_operand:QI 2 "const_0_to_255_operand")
i386.md:          (match_operand:QI 3 "const_0_to_255_operand")))
sse.md:   (match_operand 2 "const_0_to_255_operand")))
sse.md:               (match_operand 2 "const_0_to_255_operand")
sse.md:               (match_operand 3 "const_0_to_255_operand")]
sse.md:               (match_operand 3 "const_0_to_255_operand")
sse.md:               (match_operand 4 "const_0_to_255_operand")]
sse.md:             (match_operand 2 "const_0_to_255_operand")]
sse.md:             (match_operand 2 "const_0_to_255_operand")]
sse.md:    (match_operand 3 "const_0_to_255_operand")]
sse.md:    (match_operand 3 "const_0_to_255_operand")]
sse.md:     (match_operand 2 "const_0_to_255_operand")]
With QImode, const_0_to_255_operand makes no sense, valid values are
-128..127.  So, if QImode in that case is right, just use const_int_operand.
And obviously the INTVAL uses on that operand need to be prepared for the
value being -128..127.  I believe during expansion if the match_operand is
QImode that it will be turned into -128..127.
The VOIDmode ones even worse because I think nothing will truncate the
constants in there.  So, either turn those into QImode with
const_int_operand or SImode with const_0_to_255_operand, but in the latter
case change also i386-builtin.def to pass in SImode (UINT) operand rather than
QImode.

Basically, with QImode there can't be any in-range checking for error
diagnostics, all values are valid.  If we want checking, the builtin
should have SImode or similar argument (or whatever the intrinsic argument
type is) and so should be the match_operand.

E.g.
#include <x86intrin.h>

__mmask64 foo (__mmask64 x) { return _kshiftli_mask64 (x, 257); }
errors with clang/icx, warns with icc but is silently accepted by gcc.
That looks wrong to me.
extern __inline __mmask64
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_kshiftli_mask64 (__mmask64 __A, unsigned int __B)
{
  return (__mmask64) __builtin_ia32_kshiftlidi ((__mmask64) __A,
                                                (__mmask8) __B);
}
The second argument is unsigned int shift count, so shouldn't be cast
to __mmask8 which is for masks, you don't shift a mask by mask but mask by
unsigned integer.

        Jakub

Reply via email to