This is an archive of the discontinued LLVM Phabricator instance.

Don't assert on a non-pointer value being used for a "p" inline asm constraint.
ClosedPublic

Authored by aemerson on Jul 11 2023, 3:38 PM.

Details

Summary

GCC and existing codebases allow the use of integral values to be used
with this constraint. A recent change D133914 in this area started causing asserts.
Removing the assert is enough as the rest of the code works fine.

rdar://109675485

Diff Detail

Event Timeline

aemerson created this revision.Jul 11 2023, 3:38 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 11 2023, 3:38 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
aemerson requested review of this revision.Jul 11 2023, 3:38 PM

Do you have a C code? I want to see its original constraint. I'm not sure the problem is in IR's constraint or the FE that chooses p as constraint. From LangRef , p is described as An address operand. I would incline to a restricted and precise semantic for constraints in IR. Otherwise, we may face more backend crash.

As I mentioned there is *already* code out in the wild that are relying on this to work. GCC also accepts this code, and so IMO it is the defacto semantics of this feature. In this case the IR semantics are wrong.

As it currently stands clang with asserts will crash on code that it previously compiled cleanly.

The be clear, the original c constraint was also p just like in the IR. I just used the output of -emit-llvm to write an IR test.

arsenm added a subscriber: arsenm.Jul 12 2023, 8:18 AM

It doesn't matter if it's invalid, the compiler shouldn't assert

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
9374

This is also assuming address space 0

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

Sorry the inline assembly in the test isn't actually valid for ud1l, here's an example showing 'p' being used with an integer literal: https://godbolt.org/z/sPqqj5q8M

void *test()
{
  void *ret;
  asm ("movq %1, %0" : "=r" (ret) : "p" (256));
  return ret;
}

You'll find that gcc happily accepts this. For non-standardized features like this, the semantics are defined by what the implementations *do*. If GCC has always rejected this as an error, I'm happy to do the same. But GCC doesn't, so we should match them instead of breaking existing users' code (that includes throwing an error in Sema).

Now if you are convinced that this deletion of the assert is incorrect, then we can discuss a better fix. The other option is that we entirely back out the original change D133914 that introduced this regression.

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

Sorry the inline assembly in the test isn't actually valid for ud1l, here's an example showing 'p' being used with an integer literal: https://godbolt.org/z/sPqqj5q8M

void *test()
{
  void *ret;
  asm ("movq %1, %0" : "=r" (ret) : "p" (256));
  return ret;
}

You'll find that gcc happily accepts this. For non-standardized features like this, the semantics are defined by what the implementations *do*. If GCC has always rejected this as an error, I'm happy to do the same. But GCC doesn't, so we should match them instead of breaking existing users' code (that includes throwing an error in Sema).

That isn't convincing much since GCC doesn't document the p constraint somewhere. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Machine-Constraints.html

Now if you are convinced that this deletion of the assert is incorrect, then we can discuss a better fix. The other option is that we entirely back out the original change D133914 that introduced this regression.

The story started from D122220 rather than D133914. If there is a clear declaration for p constraint, I'd suggest to improve D133914, e.g., changing it to i for immediate value.

I found it works too if changing to ip there.

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

Sorry the inline assembly in the test isn't actually valid for ud1l, here's an example showing 'p' being used with an integer literal: https://godbolt.org/z/sPqqj5q8M

void *test()
{
  void *ret;
  asm ("movq %1, %0" : "=r" (ret) : "p" (256));
  return ret;
}

You'll find that gcc happily accepts this. For non-standardized features like this, the semantics are defined by what the implementations *do*. If GCC has always rejected this as an error, I'm happy to do the same. But GCC doesn't, so we should match them instead of breaking existing users' code (that includes throwing an error in Sema).

That isn't convincing much since GCC doesn't document the p constraint somewhere. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Machine-Constraints.html

https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html ?

Now if you are convinced that this deletion of the assert is incorrect, then we can discuss a better fix. The other option is that we entirely back out the original change D133914 that introduced this regression.

The story started from D122220 rather than D133914. If there is a clear declaration for p constraint, I'd suggest to improve D133914, e.g., changing it to i for immediate value.

I'm not exactly sure what you're suggesting. Ultimately: are we going to diverge from the canonical gcc behavior here for this feature?

pengfei accepted this revision.Jul 13 2023, 12:59 AM

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

My concern is removing assert don't solve the real problem. I think there are two problems here:

  1. Compiler shouldn't assert for invalid semantics. That's true. We could solve it by detecting such invalid semantics during sema checking.
  2. Application relies on invalid semantics. This is my main concern. Besides, I took a look at GCC and find it report error for it https://godbolt.org/z/zPWhsY5aj

Sorry the inline assembly in the test isn't actually valid for ud1l, here's an example showing 'p' being used with an integer literal: https://godbolt.org/z/sPqqj5q8M

void *test()
{
  void *ret;
  asm ("movq %1, %0" : "=r" (ret) : "p" (256));
  return ret;
}

You'll find that gcc happily accepts this. For non-standardized features like this, the semantics are defined by what the implementations *do*. If GCC has always rejected this as an error, I'm happy to do the same. But GCC doesn't, so we should match them instead of breaking existing users' code (that includes throwing an error in Sema).

That isn't convincing much since GCC doesn't document the p constraint somewhere. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Machine-Constraints.html

https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html ?

Now if you are convinced that this deletion of the assert is incorrect, then we can discuss a better fix. The other option is that we entirely back out the original change D133914 that introduced this regression.

The story started from D122220 rather than D133914. If there is a clear declaration for p constraint, I'd suggest to improve D133914, e.g., changing it to i for immediate value.

I'm not exactly sure what you're suggesting. Ultimately: are we going to diverge from the canonical gcc behavior here for this feature?

Thanks for the link. Sorry, I suggested to improve D122220 like this D155160

IR constraint doesn't necessarily equal to the C constraint, but we need to support the full semantics of a C constraint. Since GCC has document it well, I think it's fine to go with this patch.

This revision is now accepted and ready to land.Jul 13 2023, 12:59 AM
This revision was landed with ongoing or failed builds.Jul 13 2023, 10:46 AM
This revision was automatically updated to reflect the committed changes.