llvm-capstone/clang/test/SemaCXX/complex-folding.cpp
Chandler Carruth b29a743891 [complex] Teach the other two binary operators on complex numbers (==
and !=) to support mixed complex and real operand types.

This requires removing an assert from SemaChecking, and adding support
both to the constant evaluator and the code generator to synthesize the
imaginary part when needed. This seemed somewhat cleaner than having
just the comparison operators force real-to-complex conversions.

I've added test cases for these operations. I'm really terrified that
there were *no* tests in-tree which exercised this.

This turned up when trying to build R after my change to the complex
type lowering.

llvm-svn: 219570
2014-10-11 11:03:30 +00:00

91 lines
5.3 KiB
C++

// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify
//
// Test the constant folding of builtin complex numbers.
static_assert((0.0 + 0.0j) == (0.0 + 0.0j));
static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static_assert}}
static_assert((0.0 + 0.0j) == 0.0);
static_assert(0.0 == (0.0 + 0.0j));
static_assert(0.0 == 0.0j);
static_assert((0.0 + 1.0j) != 0.0);
static_assert(1.0 != (0.0 + 0.0j));
static_assert(0.0 != 1.0j);
// Walk around the complex plane stepping between angular differences and
// equality.
static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static_assert}}
static_assert((1.0 + 0.0j) == (1.0 + 0.0j));
static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static_assert}}
static_assert((1.0 + 1.0j) == (1.0 + 1.0j));
static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static_assert}}
static_assert((0.0 + 1.0j) == (0.0 + 1.0j));
static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static_assert}}
static_assert((-1.0 + 1.0j) == (-1.0 + 1.0j));
static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static_assert}}
static_assert((-1.0 + 0.0j) == (-1.0 + 0.0j));
static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static_assert}}
static_assert((-1.0 - 1.0j) == (-1.0 - 1.0j));
static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static_assert}}
static_assert((0.0 - 1.0j) == (0.0 - 1.0j));
static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static_assert}}
static_assert((1.0 - 1.0j) == (1.0 - 1.0j));
// Test basic mathematical folding of both complex and real operands.
static_assert(((1.0 + 0.5j) + (0.25 - 0.75j)) == (1.25 - 0.25j));
static_assert(((1.0 + 0.5j) + 0.25) == (1.25 + 0.5j));
static_assert((1.0 + (0.25 - 0.75j)) == (1.25 - 0.75j));
static_assert(((1.0 + 0.5j) - (0.25 - 0.75j)) == (0.75 + 1.25j));
static_assert(((1.0 + 0.5j) - 0.25) == (0.75 + 0.5j));
static_assert((1.0 - (0.25 - 0.75j)) == (0.75 + 0.75j));
static_assert(((1.25 + 0.5j) * (0.25 - 0.75j)) == (0.6875 - 0.8125j));
static_assert(((1.25 + 0.5j) * 0.25) == (0.3125 + 0.125j));
static_assert((1.25 * (0.25 - 0.75j)) == (0.3125 - 0.9375j));
static_assert(((1.25 + 0.5j) / (0.25 - 0.75j)) == (-0.1 + 1.7j));
static_assert(((1.25 + 0.5j) / 0.25) == (5.0 + 2.0j));
static_assert((1.25 / (0.25 - 0.75j)) == (0.5 + 1.5j));
// Test that infinities are preserved, don't turn into NaNs, and do form zeros
// when the divisor.
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1);
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1);
static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1);
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1);
static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + __builtin_inf() * 1.0j) * (__builtin_inf() + __builtin_inf() * 1.0j))) == -1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (1.0 + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__imag__(1.0 + (__builtin_inf() * 1.0j) / (1.0 + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / (1.0 + 1.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 1.0)) == 1);
static_assert(__builtin_isinf_sign(__imag__(1.0 + (__builtin_inf() * 1.0j) / 1.0)) == 1);
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / 1.0)) == 1);
static_assert(((1.0 + 1.0j) / (__builtin_inf() + 1.0j)) == (0.0 + 0.0j));
static_assert(((1.0 + 1.0j) / (1.0 + __builtin_inf() * 1.0j)) == (0.0 + 0.0j));
static_assert(((1.0 + 1.0j) / (__builtin_inf() + __builtin_inf() * 1.0j)) == (0.0 + 0.0j));
static_assert(((1.0 + 1.0j) / __builtin_inf()) == (0.0 + 0.0j));
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / (0.0 + 0.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / 0.0)) == 1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (0.0 + 0.0j))) == 1);
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) / (0.0 + 0.0j))) == 1);
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / (0.0 + 0.0j))) == 1);
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 0.0)) == 1);
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) / 0.0)) == 1);
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / 0.0)) == 1);