-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-backend-x86 Author: None (jofrn) ChangesX86 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:
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
+}
+
|
@@ -30976,6 +30976,14 @@ bool X86TargetLowering::needsCmpXchgNb(Type *MemType) const { | |||
return false; | |||
} | |||
|
|||
TargetLoweringBase::AtomicExpansionKind |
There was a problem hiding this comment.
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()) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)
2d0ad97
to
b95a021
Compare
b95a021
to
8fd1c35
Compare
it seems like this PR is stacked but not properly stacked |
✅ With the latest revision this PR passed the C/C++ code formatter. |
8fd1c35
to
f2b9675
Compare
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.
f2b9675
to
1eabd74
Compare
; 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) { |
There was a problem hiding this comment.
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() || |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
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); | ||
} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
if (const auto VT = dyn_cast<VectorType>(LI->getType())) | ||
if (VT->getElementType()->isFloatingPointTy()) |
There was a problem hiding this comment.
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
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.