This is an archive of the discontinued LLVM Phabricator instance.

[ARM] Warnings for .cpu/.fpu/.arch directives in ASM
AbandonedPublic

Authored by rengolin on Jul 15 2015, 5:47 AM.

Details

Summary

Reuse of architecture assembly directives is not an error, but can be
misleading and bring future problems, like lack of proper checking on
bad code generation, if the latter directive is less restricting than
the former, and the latter is only valid for one function.

One example is for IFUNC implementations, having multiple architectures
per compilation unit:

.fpu softvfp
func_soft_float:
  ...

func_vfp3:
  .fpu vfpv3
  ...

@ end of IFUNC block
...

.unrelated_func:
  @ assuming back to softvfp
  @ but .fpu vfpv3 leaked until here
  ...
  @ then we accidentally generate a VFP unstruction
  VMOV ...
  @ this should be an error, but the .fpu directive above masks it

The VMOV above could be a compiler code generation error, or could be a
user error, either way, we can't warn about this error, due to the leaky
nature of .fpu directives.

Another case is in inline assembly:

global_vfp = false;
my_c_func() {
  _asm_(".fpu vfpv3");
  // code that depends on VFP3
}

my_other_func() {
  if (global_vfp) {
    _asm_("VMOV ...");
  else
    _asm_("mov, mov...");
}

Here, there's an implicit contract between the C global_vfp variable and
the assmebly .fpu directive. If that contract is broken, there's no way
the compiler can warn the user, since the ".fpu vfpv3" will allow the
assembler to emit the VMOV regardless of what global_vfp is. This was
probably not the intention of the programmer when (s)he used the .fpu
directive in my_c_func().

Both examples are based on a broken design, but both appear in user code
often enough to be a problem. Multi-architecture machines and OSs are
becoming more common to exacerbate that problem, so a warning is due.

Fixes PR20757.

Problems:

  • This will turn unconditional warnings when using "clang ... file.s" and may break compilations where -Wall and -Werror are set.
    • I could add an -mllvm -disable-asm-warnings for now, until we can link Clang warning infrastructure with the assembler
  • This warns on misuse of directives, not on instruction selection issues (as outlined by the test).
    • There's no way to warn on codegen problems without changing the flags back to what's in the header, and that's a big change in behaviour from GAS.
  • This patch doesn't warn on use of the directives in inline asm.
    • That's for another patch.

Diff Detail

Event Timeline

rengolin updated this revision to Diff 29776.Jul 15 2015, 5:47 AM
rengolin retitled this revision from to [ARM] Warnings for .cpu/.fpu/.arch directives in ASM.
rengolin updated this object.
rengolin set the repository for this revision to rL LLVM.
rengolin added a subscriber: llvm-commits.
rengolin updated this object.Jul 15 2015, 5:48 AM

Won't this warn on something as simple as

clang -c -flto -arch-opt-1 test1.c
clang -c -flto -arch-opt-2 test2.c
clang test1.o test2.o -o foo -Wl,-plugin-opt=save-temps
clang -c foo.s

?

Maybe the correct thing is to warn if the state is different at the start and end of an inline assembly?

clang -c -flto -arch-opt-1 test1.c
clang -c -flto -arch-opt-2 test2.c
clang test1.o test2.o -o foo -Wl,-plugin-opt=save-temps
clang -c foo.s

No, because when we output assembly files, they have the correct set of directives in the correct place.

This only happens in two cases:

  1. Users add them to inline assembly inside functions and forget that it leaks to the rest of the file
  1. Users add them to assembly files, inside functions and forget that it leaks to the rest of the file

Maybe the correct thing is to warn if the state is different at the start and end of an inline assembly?

This wouldn't catch the case where, accidentally, the user changes back to the original, because the order of directives happen to coincide with what you're compiling.

Example:

foo:
  .fpu neon
bar:
  .fpu vfpv3

This would "pass":

$ clang -S -mfpu=vfpv3 foo.s

But this will warn:

$ clang -S -mfpu=neon foo.s

Then, say, there's a code refactoring, and foo/bar get swapped places. Then the first warns and the second doesn't.

rengolin abandoned this revision.Jul 30 2015, 3:27 AM

So, this seems to have little importance to everyone else, so I'll just abandon this revision. If anyone feels like it, they can continue from where I stopped.