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] Lowering of load atomic vector of float via cast #117189

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

Conversation

jofrn
Copy link
Contributor

@jofrn jofrn commented Nov 21, 2024

X86 backend does not lower load atomic <n x float>; yet it does so for integers, so we can cast to an integer before lowering in order to support this instruction.

@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2024

@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-backend-x86

Author: None (jofrn)

Changes

X86 backend does not lower load atomic float; yet it does so for integers, so we can cast to an integer before lowering in order to support this instruction.


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

3 Files Affected:

  • (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+8)
  • (modified) llvm/lib/Target/X86/X86ISelLowering.h (+2)
  • (added) llvm/test/CodeGen/X86/atomic-float.ll (+15)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index bcb84add65d83e..b0abd1315bd812 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -30976,6 +30976,14 @@ bool X86TargetLowering::needsCmpXchgNb(Type *MemType) const {
   return false;
 }
 
+TargetLoweringBase::AtomicExpansionKind
+X86TargetLowering::shouldCastAtomicLoadInIR(LoadInst *LI) const {
+  if (LI->getType()->isVectorTy())
+    if (cast<VectorType>(LI->getType())->getElementType()->isFloatingPointTy())
+      return AtomicExpansionKind::CastToInteger;
+  return TargetLowering::shouldCastAtomicLoadInIR(LI);
+}
+
 TargetLoweringBase::AtomicExpansionKind
 X86TargetLowering::shouldExpandAtomicStoreInIR(StoreInst *SI) const {
   Type *MemType = SI->getValueOperand()->getType();
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 14ada1721fd40e..75f8c46362327f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1808,6 +1808,8 @@ namespace llvm {
     const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
     ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
 
+    TargetLoweringBase::AtomicExpansionKind
+    shouldCastAtomicLoadInIR(LoadInst *LI) const override;
     TargetLoweringBase::AtomicExpansionKind
     shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
     TargetLoweringBase::AtomicExpansionKind
diff --git a/llvm/test/CodeGen/X86/atomic-float.ll b/llvm/test/CodeGen/X86/atomic-float.ll
new file mode 100644
index 00000000000000..fa5977808aed51
--- /dev/null
+++ b/llvm/test/CodeGen/X86/atomic-float.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s --mtriple=x86_64 --passes=atomic-expand -S -o - | FileCheck %s
+
+define float @load_atomic_float() {
+; CHECK-LABEL: define float @load_atomic_float() {
+; CHECK-NEXT:    [[SRC:%.*]] = alloca float, align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = load atomic i32, ptr [[SRC]] acquire, align 4
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float
+; CHECK-NEXT:    ret float [[TMP2]]
+;
+  %src = alloca float
+  %ret = load atomic float, ptr %src acquire, align 4
+  ret float %ret
+}
+

llvm/test/CodeGen/X86/atomic-float.ll Outdated Show resolved Hide resolved
llvm/test/CodeGen/X86/atomic-float.ll Outdated Show resolved Hide resolved
llvm/lib/Target/X86/X86ISelLowering.cpp Outdated Show resolved Hide resolved
@@ -30976,6 +30976,14 @@ bool X86TargetLowering::needsCmpXchgNb(Type *MemType) const {
return false;
}

TargetLoweringBase::AtomicExpansionKind
Copy link
Contributor

Choose a reason for hiding this comment

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

I would like to get rid of this hook. Directly promoting atomic_load to int in codegen, like any other operation, shouldn't be difficult

@@ -30976,6 +30976,14 @@ bool X86TargetLowering::needsCmpXchgNb(Type *MemType) const {
return false;
}

TargetLoweringBase::AtomicExpansionKind
X86TargetLowering::shouldCastAtomicLoadInIR(LoadInst *LI) const {
if (LI->getType()->isVectorTy())
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a test case for vector type?

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently disallowed by the IR verifier (although we should fix this)

llvm/lib/IR/Verifier.cpp Outdated Show resolved Hide resolved
@shiltian
Copy link
Contributor

it seems like this PR is stacked but not properly stacked

Copy link

github-actions bot commented Nov 25, 2024

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

jofrn and others added 2 commits December 1, 2024 14:37
Vector types on atomics are assumed to be invalid by the verifier. However,
this type can be valid if it is lowered by codegen.
X86 backend does not lower load atomic float, so it can be casted to an
integer before lowering.
llvm/test/CodeGen/X86/atomicvec-float.ll Show resolved Hide resolved
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s --mtriple=x86_64 | FileCheck %s

define float @load_atomic_float(ptr %src) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Test all the FP types, float, double, half, bfloat. fp128 if 128-bit atomics work

Check(ElTy->isIntOrPtrTy() || ElTy->isFloatingPointTy(),
"atomic load operand must have integer, pointer, or floating point "
"type!",
Check(ElTy->getScalarType()->isIntOrPtrTy() ||
Copy link
Contributor

Choose a reason for hiding this comment

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

This PR shouldn't touch the verifier, only handle codegen for atomic load / store

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is stacked on top of #117625. Please take a look. This PR handles vectors only -- renamed the title.

llvm/test/CodeGen/X86/atomicvec-float.ll Show resolved Hide resolved
Comment on lines +31161 to +31167
TargetLoweringBase::AtomicExpansionKind
X86TargetLowering::shouldCastAtomicLoadInIR(LoadInst *LI) const {
if (const auto VT = dyn_cast<VectorType>(LI->getType()))
if (VT->getElementType()->isFloatingPointTy())
return AtomicExpansionKind::CastToInteger;
return TargetLowering::shouldCastAtomicLoadInIR(LI);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be moving in the opposite direction. The existing tests atomic FP load already works, and this is regressing it to use the IR expansion (which should be deleted)

Copy link
Contributor Author

@jofrn jofrn Dec 4, 2024

Choose a reason for hiding this comment

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

That one didn't handle atomic vectors. This PR only needs atomic load of vector type to pass. Casting it here is simple for now since the hook still exists.

@jofrn jofrn changed the title [X86] Lowering of load atomic float via cast [X86] Lowering of load atomic vector of float via cast Dec 4, 2024
Comment on lines +31163 to +31164
if (const auto VT = dyn_cast<VectorType>(LI->getType()))
if (VT->getElementType()->isFloatingPointTy())
Copy link
Contributor

@arsenm arsenm Dec 6, 2024

Choose a reason for hiding this comment

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

Should move this into the default implementation. Targets can opt out as the hook is removed. Also this need not be limited to FP vectors. All vectors should cast to int

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