-
Notifications
You must be signed in to change notification settings - Fork 13.5k
release/20.x: [SDAG] Ensure load is included in output chain of sincos expansion (#140525) #140703
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
Conversation
@MacDue What do you think about merging this PR to the release branch? |
@llvm/pr-subscribers-llvm-selectiondag @llvm/pr-subscribers-backend-x86 Author: None (llvmbot) ChangesBackport c9d6249 Requested by: @MacDue Full diff: https://github.com/llvm/llvm-project/pull/140703.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b416c0efbbc4f..eecfb41c2d319 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2660,16 +2660,19 @@ bool SelectionDAG::expandMultipleResultFPLibCall(
continue;
}
MachinePointerInfo PtrInfo;
+ SDValue LoadResult =
+ getLoad(Node->getValueType(ResNo), DL, CallChain, ResultPtr, PtrInfo);
+ SDValue OutChain = LoadResult.getValue(1);
+
if (StoreSDNode *ST = ResultStores[ResNo]) {
// Replace store with the library call.
- ReplaceAllUsesOfValueWith(SDValue(ST, 0), CallChain);
+ ReplaceAllUsesOfValueWith(SDValue(ST, 0), OutChain);
PtrInfo = ST->getPointerInfo();
} else {
PtrInfo = MachinePointerInfo::getFixedStack(
getMachineFunction(), cast<FrameIndexSDNode>(ResultPtr)->getIndex());
}
- SDValue LoadResult =
- getLoad(Node->getValueType(ResNo), DL, CallChain, ResultPtr, PtrInfo);
+
Results.push_back(LoadResult);
}
diff --git a/llvm/test/CodeGen/X86/pr140491-sincos-lifetimes.ll b/llvm/test/CodeGen/X86/pr140491-sincos-lifetimes.ll
new file mode 100644
index 0000000000000..2ca99bdc4b316
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr140491-sincos-lifetimes.ll
@@ -0,0 +1,70 @@
+; RUN: llc < %s | FileCheck %s
+
+; This test is reduced from https://github.com/llvm/llvm-project/issues/140491.
+; It checks that when `@llvm.sincos.f32` is expanded to a call to
+; `sincosf(float, float* out_sin, float* out_cos)` and the store of `%cos` to
+; `%computed` is folded into the `sincosf` call. The use of `%cos`in the later
+; `fneg %cos` -- which expands to a load of `%computed`, will perform the load
+; before the `@llvm.lifetime.end.p0(%computed)` to ensure the correct value is
+; taken for `%cos`.
+
+target triple = "x86_64-sie-ps5"
+
+declare void @use_ptr(ptr readonly)
+
+define i32 @sincos_stack_slot_with_lifetime(float %in) {
+; CHECK-LABEL: sincos_stack_slot_with_lifetime:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: pushq %rbx
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: subq $32, %rsp
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: .cfi_offset %rbx, -16
+; CHECK-NEXT: leaq 12(%rsp), %rdi
+; CHECK-NEXT: leaq 8(%rsp), %rbx
+; CHECK-NEXT: movq %rbx, %rsi
+; CHECK-NEXT: callq sincosf@PLT
+; CHECK-NEXT: movss 8(%rsp), %xmm0 # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT: movaps %xmm0, 16(%rsp) # 16-byte Spill
+; CHECK-NEXT: movq %rbx, %rdi
+; CHECK-NEXT: callq use_ptr
+; CHECK-NEXT: movss 12(%rsp), %xmm0 # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT: movss %xmm0, 8(%rsp)
+; CHECK-NEXT: leaq 8(%rsp), %rdi
+; CHECK-NEXT: callq use_ptr
+; CHECK-NEXT: movaps 16(%rsp), %xmm0 # 16-byte Reload
+; CHECK-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT: movss %xmm0, 8(%rsp)
+; CHECK-NEXT: leaq 8(%rsp), %rdi
+; CHECK-NEXT: callq use_ptr
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: addq $32, %rsp
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: popq %rbx
+; CHECK-NEXT: .cfi_def_cfa_offset 8
+; CHECK-NEXT: retq
+entry:
+ %computed = alloca float, align 4
+ %computed1 = alloca float, align 4
+ %computed3 = alloca float, align 4
+ %sincos = tail call { float, float } @llvm.sincos.f32(float %in)
+ %sin = extractvalue { float, float } %sincos, 0
+ %cos = extractvalue { float, float } %sincos, 1
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %computed)
+ store float %cos, ptr %computed, align 4
+ call void @use_ptr(ptr nonnull %computed)
+ call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %computed)
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %computed1)
+ %fneg_sin = fneg float %sin
+ store float %fneg_sin, ptr %computed1, align 4
+ call void @use_ptr(ptr nonnull %computed1)
+ call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %computed1)
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %computed3)
+ %fneg_cos = fneg float %cos
+ store float %fneg_cos, ptr %computed3, align 4
+ call void @use_ptr(ptr nonnull %computed3)
+ call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %computed3)
+ ret i32 0
+}
+
|
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.
LGTM
…lvm#140525) The load not being included in the chain meant that it could materialize after a `@llvm.lifetime.end` annotation on the pointer. This could result in miscompiles if the stack slot is reused for another value. Fixes llvm#140491 (cherry picked from commit c9d6249)
@MacDue (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
Backport c9d6249
Requested by: @MacDue