aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/X86/negative-sin.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/X86/negative-sin.ll')
-rw-r--r--test/CodeGen/X86/negative-sin.ll101
1 files changed, 97 insertions, 4 deletions
diff --git a/test/CodeGen/X86/negative-sin.ll b/test/CodeGen/X86/negative-sin.ll
index 76e557b84225d..16258f4794028 100644
--- a/test/CodeGen/X86/negative-sin.ll
+++ b/test/CodeGen/X86/negative-sin.ll
@@ -1,12 +1,105 @@
-; RUN: llc < %s -enable-unsafe-fp-math -march=x86-64 | FileCheck %s
-; CHECK-NOT: {{addsd|subsd|xor}}
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=avx | FileCheck %s
declare double @sin(double %f)
-define double @foo(double %e)
-{
+; When the subs are strict, they can't be removed because of signed zero.
+
+define double @strict(double %e) nounwind {
+; CHECK-LABEL: strict:
+; CHECK: # BB#0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: vxorpd %xmm1, %xmm1, %xmm1
+; CHECK-NEXT: vsubsd %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: callq sin
+; CHECK-NEXT: vxorpd %xmm1, %xmm1, %xmm1
+; CHECK-NEXT: vsubsd %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: popq %rax
+; CHECK-NEXT: retq
+;
+ %f = fsub double 0.0, %e
+ %g = call double @sin(double %f) readonly
+ %h = fsub double 0.0, %g
+ ret double %h
+}
+
+; 'fast' implies no-signed-zeros, so the negates fold away.
+; The 'sin' does not need any fast-math-flags for this transform.
+
+define double @fast(double %e) nounwind {
+; CHECK-LABEL: fast:
+; CHECK: # BB#0:
+; CHECK-NEXT: jmp sin
+;
+ %f = fsub fast double 0.0, %e
+ %g = call double @sin(double %f) readonly
+ %h = fsub fast double 0.0, %g
+ ret double %h
+}
+
+; No-signed-zeros is all that we need for this transform.
+
+define double @nsz(double %e) nounwind {
+; CHECK-LABEL: nsz:
+; CHECK: # BB#0:
+; CHECK-NEXT: jmp sin
+;
+ %f = fsub nsz double 0.0, %e
+ %g = call double @sin(double %f) readonly
+ %h = fsub nsz double 0.0, %g
+ ret double %h
+}
+
+; The 1st negate is strict, so we can't kill that sub, but the 2nd disappears.
+
+define double @semi_strict1(double %e) nounwind {
+; CHECK-LABEL: semi_strict1:
+; CHECK: # BB#0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: vxorpd %xmm1, %xmm1, %xmm1
+; CHECK-NEXT: vsubsd %xmm0, %xmm1, %xmm0
+; CHECK-NEXT: callq sin
+; CHECK-NEXT: vxorpd {{.*}}(%rip), %xmm0, %xmm0
+; CHECK-NEXT: popq %rax
+; CHECK-NEXT: retq
+;
+ %f = fsub double 0.0, %e
+ %g = call double @sin(double %f) readonly
+ %h = fsub nsz double 0.0, %g
+ ret double %h
+}
+
+; The 2nd negate is strict, so we can't kill it. It becomes an add of zero instead.
+
+define double @semi_strict2(double %e) nounwind {
+; CHECK-LABEL: semi_strict2:
+; CHECK: # BB#0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq sin
+; CHECK-NEXT: vxorpd %xmm1, %xmm1, %xmm1
+; CHECK-NEXT: vaddsd %xmm1, %xmm0, %xmm0
+; CHECK-NEXT: popq %rax
+; CHECK-NEXT: retq
+;
+ %f = fsub nsz double 0.0, %e
+ %g = call double @sin(double %f) readonly
+ %h = fsub double 0.0, %g
+ ret double %h
+}
+
+; FIXME:
+; Auto-upgrade function attribute to IR-level fast-math-flags.
+
+define double @fn_attr(double %e) nounwind #0 {
+; CHECK-LABEL: fn_attr:
+; CHECK: # BB#0:
+; CHECK-NEXT: jmp sin
+;
%f = fsub double 0.0, %e
%g = call double @sin(double %f) readonly
%h = fsub double 0.0, %g
ret double %h
}
+
+attributes #0 = { "unsafe-fp-math"="true" }
+