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

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

Merged
merged 1 commit into from
Feb 28, 2024
Merged

Conversation

AtariDreams
Copy link
Contributor

@AtariDreams AtariDreams commented Feb 20, 2024

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

@llvmbot
Copy link
Collaborator

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.

@AtariDreams AtariDreams changed the title Resolve fixme: create cld only when needed [X86] Resolve FIXME: Create cld only when needed Feb 21, 2024
@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)?

@AtariDreams
Copy link
Contributor Author

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?

@AtariDreams
Copy link
Contributor Author

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!

@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."?

@AtariDreams
Copy link
Contributor Author

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

@AtariDreams
Copy link
Contributor Author

Test failure is unrelated to patch.

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?

@AtariDreams
Copy link
Contributor Author

@AtariDreams Do you have commit access?

@RKSimon I do not.

@RKSimon RKSimon merged commit 0a54b36 into llvm:main Feb 28, 2024
3 of 4 checks passed
@AtariDreams AtariDreams 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?

@AtariDreams
Copy link
Contributor Author

#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.

None yet

5 participants