D87279 exposed an existing reliance on tied operands for CallBr to
process its constraints for indirect detination input parameters. A case
of using asm goto with a single output with the +r constraint on a
register variable caused an ICE.
The code originally was very careful to only consider arguments to the
asm which were the indirect targets of the callbr. Because we didn't
initially have support for outputs from callbr (ie. asm goto didn't
originally support output constraints), we didn't need to worry about
non-destination inputs occurring after indirect destination operands, as
can occur when outputs are tied (ie. the +r output constraint).
This became brittle when adding support for "asm goto with outputs"
(D69868) and finally broke when D87279 changed tied operands to no
longer use backreference-like tied inputs for register variables.
The LangRef section titled "Inline Asm Constraint String" currently
states:
The constraints must always be given in that order: outputs first,
then inputs, then clobbers. They cannot be intermingled.
There is an ambiguity where the indirect destinations of a callbr
are inputs, but they have no guaranteed order with respect to other
inputs. In fact, clang can easily intermingle these with other
non-indirect destination inputs as seen when using tied operands.
Codify the existing order of input arguments from clang into the LangRef
to be able to disambiguate this case, and don't just bias the range
check based on matching backreference-like operands. By following this
convention, we don't need to keep track of which arguments to the inline
assembler expression are intended to be the indirect destinations; we
can remateralize that information in SelectionDagBuilder when needed.
Reported-by: kernel test robot <lkp@intel.com>
Fixes: https://github.com/ClangBuiltLinux/linux/issues/1512
It might be good to have a test from one of your examples where a block addresses are used as inputs but not indirect destinations. From above: