Skip to content

Commit 7d2c289

Browse files
MacDuellvmbot
authored andcommitted
[SDAG] Ensure load is included in output chain of sincos expansion (#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 #140491 (cherry picked from commit c9d6249)
1 parent 5befd1f commit 7d2c289

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2660,16 +2660,19 @@ bool SelectionDAG::expandMultipleResultFPLibCall(
26602660
continue;
26612661
}
26622662
MachinePointerInfo PtrInfo;
2663+
SDValue LoadResult =
2664+
getLoad(Node->getValueType(ResNo), DL, CallChain, ResultPtr, PtrInfo);
2665+
SDValue OutChain = LoadResult.getValue(1);
2666+
26632667
if (StoreSDNode *ST = ResultStores[ResNo]) {
26642668
// Replace store with the library call.
2665-
ReplaceAllUsesOfValueWith(SDValue(ST, 0), CallChain);
2669+
ReplaceAllUsesOfValueWith(SDValue(ST, 0), OutChain);
26662670
PtrInfo = ST->getPointerInfo();
26672671
} else {
26682672
PtrInfo = MachinePointerInfo::getFixedStack(
26692673
getMachineFunction(), cast<FrameIndexSDNode>(ResultPtr)->getIndex());
26702674
}
2671-
SDValue LoadResult =
2672-
getLoad(Node->getValueType(ResNo), DL, CallChain, ResultPtr, PtrInfo);
2675+
26732676
Results.push_back(LoadResult);
26742677
}
26752678

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
; RUN: llc < %s | FileCheck %s
2+
3+
; This test is reduced from https://github.com/llvm/llvm-project/issues/140491.
4+
; It checks that when `@llvm.sincos.f32` is expanded to a call to
5+
; `sincosf(float, float* out_sin, float* out_cos)` and the store of `%cos` to
6+
; `%computed` is folded into the `sincosf` call. The use of `%cos`in the later
7+
; `fneg %cos` -- which expands to a load of `%computed`, will perform the load
8+
; before the `@llvm.lifetime.end.p0(%computed)` to ensure the correct value is
9+
; taken for `%cos`.
10+
11+
target triple = "x86_64-sie-ps5"
12+
13+
declare void @use_ptr(ptr readonly)
14+
15+
define i32 @sincos_stack_slot_with_lifetime(float %in) {
16+
; CHECK-LABEL: sincos_stack_slot_with_lifetime:
17+
; CHECK: # %bb.0: # %entry
18+
; CHECK-NEXT: pushq %rbx
19+
; CHECK-NEXT: .cfi_def_cfa_offset 16
20+
; CHECK-NEXT: subq $32, %rsp
21+
; CHECK-NEXT: .cfi_def_cfa_offset 48
22+
; CHECK-NEXT: .cfi_offset %rbx, -16
23+
; CHECK-NEXT: leaq 12(%rsp), %rdi
24+
; CHECK-NEXT: leaq 8(%rsp), %rbx
25+
; CHECK-NEXT: movq %rbx, %rsi
26+
; CHECK-NEXT: callq sincosf@PLT
27+
; CHECK-NEXT: movss 8(%rsp), %xmm0 # xmm0 = mem[0],zero,zero,zero
28+
; CHECK-NEXT: movaps %xmm0, 16(%rsp) # 16-byte Spill
29+
; CHECK-NEXT: movq %rbx, %rdi
30+
; CHECK-NEXT: callq use_ptr
31+
; CHECK-NEXT: movss 12(%rsp), %xmm0 # xmm0 = mem[0],zero,zero,zero
32+
; CHECK-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
33+
; CHECK-NEXT: movss %xmm0, 8(%rsp)
34+
; CHECK-NEXT: leaq 8(%rsp), %rdi
35+
; CHECK-NEXT: callq use_ptr
36+
; CHECK-NEXT: movaps 16(%rsp), %xmm0 # 16-byte Reload
37+
; CHECK-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
38+
; CHECK-NEXT: movss %xmm0, 8(%rsp)
39+
; CHECK-NEXT: leaq 8(%rsp), %rdi
40+
; CHECK-NEXT: callq use_ptr
41+
; CHECK-NEXT: xorl %eax, %eax
42+
; CHECK-NEXT: addq $32, %rsp
43+
; CHECK-NEXT: .cfi_def_cfa_offset 16
44+
; CHECK-NEXT: popq %rbx
45+
; CHECK-NEXT: .cfi_def_cfa_offset 8
46+
; CHECK-NEXT: retq
47+
entry:
48+
%computed = alloca float, align 4
49+
%computed1 = alloca float, align 4
50+
%computed3 = alloca float, align 4
51+
%sincos = tail call { float, float } @llvm.sincos.f32(float %in)
52+
%sin = extractvalue { float, float } %sincos, 0
53+
%cos = extractvalue { float, float } %sincos, 1
54+
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %computed)
55+
store float %cos, ptr %computed, align 4
56+
call void @use_ptr(ptr nonnull %computed)
57+
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %computed)
58+
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %computed1)
59+
%fneg_sin = fneg float %sin
60+
store float %fneg_sin, ptr %computed1, align 4
61+
call void @use_ptr(ptr nonnull %computed1)
62+
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %computed1)
63+
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %computed3)
64+
%fneg_cos = fneg float %cos
65+
store float %fneg_cos, ptr %computed3, align 4
66+
call void @use_ptr(ptr nonnull %computed3)
67+
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %computed3)
68+
ret i32 0
69+
}
70+

0 commit comments

Comments
 (0)