[cfe-dev] (not) initializing assembly outputs with -ftrivial-auto-var-init

James Y Knight via cfe-dev cfe-dev at lists.llvm.org
Tue Mar 26 10:51:00 PDT 2019


On Tue, Mar 26, 2019 at 11:34 AM Alexander Potapenko <glider at google.com>
wrote:

> Right now there's a handful of places in the kernel where we have to
> use __attribute__((uninitialized)) just to avoid creating an extra
> initializer:
> https://github.com/google/kmsan/commit/00387943691e6466659daac0312c8c5d8f9420b9
> and
> https://github.com/google/kmsan/commit/2954f1c33a81c6f15c7331876f5b6e2fec0d631f
> All those assembly directives are using local scalar variables of size
> <= 8 bytes as "=qm" outputs, so we can narrow the problem down to "let
> DSE remove redundant stores to local scalars that are used as asm()
> "m" outputs"
> False positives will sure be possible in theory, but hopefully rare in
> practice.
>
> I would still love to know what's the main source of truth for the
> semantics of asm() constraints.
> For example, we've noticed that the BSF instruction, which can be used
> as follows:
>
> unsigned long ffs(unsigned long word) {
>   unsigned long ret;
>   asm("rep; bsf %1,%0" : "=r" (ret) : "rm" (word));
>   return ret;
> }
>
> isn't guaranteed to initialize its output in the case |word| is 0
> (according to unnamed Intel architect, it just zeroes out the top 32
> bits of the return value).
> Therefore the elimination of dead stores to |ret| done by both Clang
> and GCC is correct only if the callers are careful enough


I'm not sure what you mean. If the asm code says "=r" (or "=" *anything*)
and fails to write a value to the variable, then you cannot use that value
afterwards. That's an error.

It's just like "oops, I didn't return a value from the function":

int novalueret(int word) { if (word != 0) return 5; }
int f(int word) {
  int ret;
  ret = novalueret(word);
  return ret;
}

A mechanism to verify the correctness of arbitrary inline-asm, and check
its constraints match is certainly an interesting project, and one that's
been discussed before. But if that's even feasible at ALL (which I'm rather
skeptical of), that's going to need to be an entirely separate
sanitization/hardening/warning framework.

In the rest of the compiler, if the asm constraints say something, we NEED
to trust that the instructions actually do so -- having that power is what
inline asm is FOR. There is nothing else useful that we can do.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190326/314c1cec/attachment.html>


More information about the cfe-dev mailing list