Skip to content

[X86] Resolve FIXME: Create cld only when needed #82415

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

Merged
merged 1 commit into from
Feb 28, 2024
Merged

Conversation

AZero13
Copy link
Contributor

@AZero13 AZero13 commented Feb 20, 2024

Only use cld when we also have rep instructions, are calling a function, or contain inline asm.

@llvmbot
Copy link
Member

llvmbot commented Feb 20, 2024

@llvm/pr-subscribers-backend-x86

Author: AtariDreams (AtariDreams)

Changes

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

1 Files Affected:

  • (modified) llvm/lib/Target/X86/X86FrameLowering.cpp (+40-4)
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index be416fb0db0695..569cd3330de2f2 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -2194,13 +2194,49 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
   // flag (DF in EFLAGS register). Clear this flag by creating "cld" instruction
   // in each prologue of interrupt handler function.
   //
-  // FIXME: Create "cld" instruction only in these cases:
+  // Create "cld" instruction only in these cases:
   // 1. The interrupt handling function uses any of the "rep" instructions.
   // 2. Interrupt handling function calls another function.
   //
-  if (Fn.getCallingConv() == CallingConv::X86_INTR)
-    BuildMI(MBB, MBBI, DL, TII.get(X86::CLD))
-        .setMIFlag(MachineInstr::FrameSetup);
+  if (Fn.getCallingConv() == CallingConv::X86_INTR) {
+    bool NeedsCLD = false;
+
+    // Check if the function calls another function.
+    for (const BasicBlock &BB : Fn) {
+      for (const Instruction &I : BB) {
+        if (isa<CallInst>(I)) {
+          NeedsCLD = true;
+          break;
+        }
+
+        // Check for rep opcode.
+        if (auto *MI = dyn_cast<MachineInstr>(&I)) {
+          unsigned Opcode = MI->getOpcode();
+          if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
+            NeedsCLD = true;
+            break;
+          }
+        }
+      }
+    }
+
+    // Check if the function uses any "rep" instructions.
+    if (!NeedsCLD) {
+      for (const BasicBlock &BB : Fn) {
+        for (const Instruction &I : BB) {
+          if (/* check if I is a "rep" instruction */) {
+            NeedsCLD = true;
+            break;
+          }
+        }
+      }
+    }
+
+    if (NeedsCLD) {
+      BuildMI(MBB, MBBI, DL, TII.get(X86::CLD))
+          .setMIFlag(MachineInstr::FrameSetup);
+    }
+  }
 
   // At this point we know if the function has WinCFI or not.
   MF.setHasWinCFI(HasWinCFI);

Copy link

⚠️ We detected that you are using a GitHub private e-mail address to contribute to the repo.
Please turn off Keep my email addresses private setting in your account.
See LLVM Discourse for more information.

@AZero13 AZero13 force-pushed the cld branch 5 times, most recently from bdc74a8 to 921ac0d Compare February 20, 2024 22:08
@AZero13 AZero13 force-pushed the cld branch 3 times, most recently from 7b17736 to 37ab03e Compare February 21, 2024 00:40
@AZero13 AZero13 changed the title Resolve fixme: create cld only when needed [X86] Resolve FIXME: Create cld only when needed Feb 21, 2024
@AZero13 AZero13 requested a review from topperc February 21, 2024 01:10
@AZero13 AZero13 force-pushed the cld branch 2 times, most recently from d1e2c47 to 91c0f9e Compare February 21, 2024 02:51
@AZero13 AZero13 requested a review from topperc February 21, 2024 16:48
@AZero13 AZero13 force-pushed the cld branch 8 times, most recently from 9b026ca to d2326d2 Compare February 22, 2024 18:43
@RKSimon
Copy link
Collaborator

RKSimon commented Feb 24, 2024

Based off #60527 - should we be also detecting use of std for a case to add cld at function exit? Or can we just rely on the InlineAsm case for now as I think that's the only way that std can occur (in which we should probably explicitly mention std instructions there)?

@AZero13
Copy link
Contributor Author

AZero13 commented Feb 25, 2024

Based off #60527 - should we be also detecting use of std for a case to add cld at function exit? Or can we just rely on the InlineAsm case for now as I think that's the only way that std can occur (in which we should probably explicitly mention std instructions there)?

I think we should rely on inline asm for now. Though, I am not aware that the compiler cannot emit an std instruction, right?

@AZero13
Copy link
Contributor Author

AZero13 commented Feb 25, 2024

Based off #60527 - should we be also detecting use of std for a case to add cld at function exit? Or can we just rely on the InlineAsm case for now as I think that's the only way that std can occur (in which we should probably explicitly mention std instructions there)?

Done!

@AZero13 AZero13 force-pushed the cld branch 3 times, most recently from fe5cc17 to af5a206 Compare February 26, 2024 00:20
@RKSimon
Copy link
Collaborator

RKSimon commented Feb 26, 2024

Update the patch description:
"Only use cld when we also have rep instructions or are calling a function."
--> "Only use cld when we also have rep instructions, are calling a function or contain inline asm."?

@AZero13
Copy link
Contributor Author

AZero13 commented Feb 26, 2024

Update the patch description: "Only use cld when we also have rep instructions or are calling a function." --> "Only use cld when we also have rep instructions, are calling a function or contain inline asm."?

Done! @RKSimon

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

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

LGTM

@AZero13
Copy link
Contributor Author

AZero13 commented Feb 26, 2024

Test failure is unrelated to patch.

@AZero13 AZero13 force-pushed the cld branch 5 times, most recently from 959987a to ce2b03c Compare February 27, 2024 20:06
Only use cld when we also have rep instructions, are calling a function, or contain inline asm.
@RKSimon
Copy link
Collaborator

RKSimon commented Feb 28, 2024

@AtariDreams Do you have commit access?

@AZero13
Copy link
Contributor Author

AZero13 commented Feb 28, 2024

@AtariDreams Do you have commit access?

@RKSimon I do not.

@RKSimon RKSimon merged commit 0a54b36 into llvm:main Feb 28, 2024
@AZero13 AZero13 deleted the cld branch February 29, 2024 15:59
@gooncreeper
Copy link

@AtariDreams I don't know if I'm missing something, but shouldn't we emit cld for any string instruction, not just rep?

@AZero13
Copy link
Contributor Author

AZero13 commented Mar 29, 2024

#86557 I was thinking the same thing.

@topperc
Copy link
Collaborator

topperc commented Mar 29, 2024

@AtariDreams I don't know if I'm missing something, but shouldn't we emit cld for any string instruction, not just rep?

I don't think the X86 backend ever emits a string instruction without REP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants