Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PowerPC] Make "ca" aliased to "xer" #77557

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Conversation

bzEq
Copy link
Collaborator

@bzEq bzEq commented Jan 10, 2024

ca is not accepted in clobber list of inline assembly right now. Make ca aliased to xer, so it can be accepted in clobber list.

Fixes #77549.

@bzEq bzEq self-assigned this Jan 10, 2024
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 10, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 10, 2024

@llvm/pr-subscribers-clang

Author: Kai Luo (bzEq)

Changes

ca is not accepted in clobber list of inline assembly right now. Make ca aliased to xer, so it can be accepted in clobber list.

Fixes #77549.


Full diff: https://github.com/llvm/llvm-project/pull/77557.diff

2 Files Affected:

  • (modified) clang/lib/Basic/Targets/PPC.cpp (+4-1)
  • (added) clang/test/CodeGen/ppc-register-names.c (+14)
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 045c273f03c7a0..abf685f8883971 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -782,6 +782,9 @@ ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
     // While some of these aliases do map to different registers
     // they still share the same register name.
+    // Strictly speaking, "ca" is a subregister of "xer". However
+    // currently we don't model other bit fields of "xer", so treat
+    // "ca" aliasing to "xer".
     {{"0"}, "r0"},     {{"1", "sp"}, "r1"}, {{"2"}, "r2"},
     {{"3"}, "r3"},     {{"4"}, "r4"},       {{"5"}, "r5"},
     {{"6"}, "r6"},     {{"7"}, "r7"},       {{"8"}, "r8"},
@@ -803,7 +806,7 @@ const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
     {{"fr22"}, "f22"}, {{"fr23"}, "f23"},   {{"fr24"}, "f24"},
     {{"fr25"}, "f25"}, {{"fr26"}, "f26"},   {{"fr27"}, "f27"},
     {{"fr28"}, "f28"}, {{"fr29"}, "f29"},   {{"fr30"}, "f30"},
-    {{"fr31"}, "f31"}, {{"cc"}, "cr0"},
+    {{"fr31"}, "f31"}, {{"cc"}, "cr0"},     {{"ca"},   "xer"},
 };
 
 ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
diff --git a/clang/test/CodeGen/ppc-register-names.c b/clang/test/CodeGen/ppc-register-names.c
new file mode 100644
index 00000000000000..209488c2e5f1ae
--- /dev/null
+++ b/clang/test/CodeGen/ppc-register-names.c
@@ -0,0 +1,14 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang -target powerpc64le -c %s -mllvm -stop-after=finalize-isel -o - | \
+// RUN:   FileCheck %s
+// RUN: %clang -target powerpc64 -c %s -mllvm -stop-after=finalize-isel -o - | \
+// RUN:   FileCheck %s
+
+void test_function(void) {
+  asm volatile("":::"ca");
+  asm volatile("":::"xer");
+  // CHECK: call void asm sideeffect "", "~{xer}"()
+  // CHECK: call void asm sideeffect "", "~{xer}"()
+  // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $xer
+  // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $xer
+}

Copy link

github-actions bot commented Jan 10, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Comment on lines +2 to +5
// RUN: %clang -target powerpc64le -c %s -mllvm -stop-after=finalize-isel -o - | \
// RUN: FileCheck %s
// RUN: %clang -target powerpc64 -c %s -mllvm -stop-after=finalize-isel -o - | \
// RUN: FileCheck %s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use %clang_cc1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks %clang_cc doesn't accept -mllvm.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why -c here? I think it will work with -S.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-mllvm -stop-after=finalize-isel should make -c and -S no difference, I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because clang -cc1 doesn't recognize -c, instead, it reads -emit-obj.

@@ -782,6 +782,8 @@ ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
// While some of these aliases do map to different registers
// they still share the same register name.
// Strictly speaking, "ca" is a subregister of "xer". However currently we
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a FIXME:?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a note. I don't think we are modeling other fields like SO, OV in XER in the near future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of this patch was to allow the compiler to add "ca" as part of the clobber list.

However, even if the compiler doesn't track other bits in the XER we may have to add them so that the compiler doesn't complain when a user tries to specify the bit. If that happens, would we have to add those other fields and then specify them as proper subregs of XER?

Also, which of these bits, if any, does GCC support on PowerPC?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that happens, would we have to add those other fields and then specify them as proper subregs of XER?

I think so. However, existing instructions look not using other fields like OV and OV32.

does GCC support on PowerPC?

Currently, GCC looks only support xer and ca. See https://godbolt.org/z/6qWqc3Pdd. I have tried using ov, hit CE.

@bzEq
Copy link
Collaborator Author

bzEq commented Jan 11, 2024

Add test for backend and adjust comment of CARRY.

// Carry bit. In the architecture this is really bit 0 of the XER register
// (which really is SPR register 1); this is the only bit interesting to a
// compiler.
// Carry bit. In the architecture this is really bit 2 of the 32-bit XER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:
The XER register is actually a 64 bit register. I realize that the first 32 bits are technically reserved (as well as a number of other bits like 35-43) but it is still a 64 bit register. In that way the carry bit becomes bit 34.

I also looked above and it seems that we incorrectly document SPR as being one of a number of 32 bit registers. The issue is that some of the SPR are 32 bit and others are 64 bit. It really depends on which SPR we are looking at.

I may be missing something here. Is there a history of the compiler assuming that all SPR are 32 bits?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a history of the compiler assuming that all SPR are 32 bits?

The code was written more than a decade ago. I guess authors referenced The PowerPC Compiler Writer’s Guide. Figure 2-1 of the book shows XER, FPER, FPSCR are 32-bit width even under 64-bit environment.

In appendix, there is

Carry bit Bit 2 in the Fixed-Point Exception Register (XER).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update it according to OpenPower's ISA, since it's more generally available.

@@ -782,6 +782,8 @@ ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
// While some of these aliases do map to different registers
// they still share the same register name.
// Strictly speaking, "ca" is a subregister of "xer". However currently we
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of this patch was to allow the compiler to add "ca" as part of the clobber list.

However, even if the compiler doesn't track other bits in the XER we may have to add them so that the compiler doesn't complain when a user tries to specify the bit. If that happens, would we have to add those other fields and then specify them as proper subregs of XER?

Also, which of these bits, if any, does GCC support on PowerPC?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[PowerPC] ca is not supported in clobber list of inline assembly
4 participants