Files
clang-p2996/llvm/test/CodeGen/X86/pr49393.ll
Craig Topper 74e6030bcb [TargetLowering] Use HandleSDNodes to prevent nodes from being deleted by recursive calls in getNegatedExpression.
For binary or ternary ops we call getNegatedExpression multiple
times and then compare costs. While we're doing this we need to
hold a node from the first call across the second call, but its
not yet attached to the DAG. Its possible the second call creates
an identical node and then decides it didn't need it so will try
to delete it if it has no uses. This can cause a reference to the
node we're holding further up the call stack to become invalidated.

To prevent this, we can use a HandleSDNode to artifically give
the node a use without connecting it to the DAG.

I've used a std::list of HandleSDNodes so we can create handles
only when we have a node to hold. HandleSDNode does not have
default constructor and cannot be copied or moved.

Fixes PR49393.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D97914
2021-03-04 22:48:25 -08:00

56 lines
2.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
define void @f() {
; CHECK-LABEL: f:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB0_1: # %for.cond
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: imull %eax, %eax
; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
; CHECK-NEXT: movapd %xmm0, %xmm1
; CHECK-NEXT: mulsd %xmm0, %xmm1
; CHECK-NEXT: subsd %xmm0, %xmm1
; CHECK-NEXT: cwtl
; CHECK-NEXT: xorps %xmm2, %xmm2
; CHECK-NEXT: cvtsi2sd %eax, %xmm2
; CHECK-NEXT: mulsd %xmm0, %xmm2
; CHECK-NEXT: mulsd %xmm0, %xmm2
; CHECK-NEXT: movapd %xmm2, %xmm3
; CHECK-NEXT: mulsd %xmm1, %xmm3
; CHECK-NEXT: mulsd %xmm0, %xmm2
; CHECK-NEXT: subsd %xmm3, %xmm1
; CHECK-NEXT: addsd %xmm2, %xmm1
; CHECK-NEXT: cvttsd2si %xmm1, %eax
; CHECK-NEXT: jmp .LBB0_1
entry:
br label %for.cond
for.cond: ; preds = %for.cond, %entry
%b.0 = phi i16 [ 0, %entry ], [ %conv77, %for.cond ]
%mul18 = mul i16 %b.0, %b.0
%arrayidx.real = load double, double* undef, align 1
%arrayidx.imag = load double, double* undef, align 1
%mul_ac = fmul fast double %arrayidx.real, %arrayidx.real
%0 = fadd fast double 0.000000e+00, %arrayidx.real
%sub.r = fsub fast double %mul_ac, %0
%sub.i = fsub fast double 0.000000e+00, %arrayidx.imag
%conv28 = sitofp i16 %mul18 to double
%mul_bc32 = fmul fast double %arrayidx.imag, %conv28
%mul_bd46 = fmul fast double %mul_bc32, %arrayidx.imag
%mul_r49 = fsub fast double 0.000000e+00, %mul_bd46
%mul_ac59 = fmul fast double %mul_r49, %sub.r
%mul_bc48 = fmul fast double %mul_bc32, %arrayidx.real
%mul_i50 = fadd fast double 0.000000e+00, %mul_bc48
%1 = fmul fast double %mul_i50, %sub.i
%.neg = fneg fast double %0
%.neg19 = fmul fast double %1, -1.000000e+00
%.neg20 = fadd fast double %.neg, %mul_ac
%2 = fadd fast double %.neg20, %mul_ac59
%sub.r75 = fadd fast double %2, %.neg19
%conv77 = fptosi double %sub.r75 to i16
br label %for.cond
}