|  | // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s | 
|  |  | 
|  | typedef __attribute__(( ext_vector_type(4) )) float float4; | 
|  | typedef __attribute__(( ext_vector_type(2) )) float float2; | 
|  | typedef __attribute__(( ext_vector_type(4) )) int int4; | 
|  | typedef __attribute__(( ext_vector_type(4) )) unsigned int uint4; | 
|  |  | 
|  | // CHECK: @foo = {{(dso_local )?}}global <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00> | 
|  | float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 }; | 
|  |  | 
|  | // CHECK: @bar = {{(dso_local )?}}constant <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 0x7FF0000000000000> | 
|  | const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() }; | 
|  |  | 
|  | // CHECK: @test1 | 
|  | // CHECK: fadd <4 x float> | 
|  | float4 test1(float4 V) { | 
|  | return V.wzyx+V; | 
|  | } | 
|  |  | 
|  | float2 vec2, vec2_2; | 
|  | float4 vec4, vec4_2; | 
|  | float f; | 
|  |  | 
|  | // CHECK: @test2 | 
|  | // CHECK: shufflevector {{.*}} <i32 0, i32 1> | 
|  | // CHECK: extractelement | 
|  | // CHECK: shufflevector {{.*}} <i32 1, i32 1, i32 1, i32 1> | 
|  | // CHECK: insertelement | 
|  | // CHECK: shufflevector {{.*}} <i32 1, i32 0> | 
|  | void test2(void) { | 
|  | vec2 = vec4.xy;  // shorten | 
|  | f = vec2.x;      // extract elt | 
|  | vec4 = vec4.yyyy;  // splat | 
|  |  | 
|  | vec2.x = f;      // insert one. | 
|  | vec2.yx = vec2; // reverse | 
|  | } | 
|  |  | 
|  | // CHECK: @test3 | 
|  | // CHECK: store <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00> | 
|  | void test3(float4 *out) { | 
|  | *out = ((float4) {1.0f, 2.0f, 3.0f, 4.0f }); | 
|  | } | 
|  |  | 
|  | // CHECK: @test4 | 
|  | // CHECK: store <4 x float> | 
|  | // CHECK: store <4 x float> | 
|  | void test4(float4 *out) { | 
|  | float a = 1.0f; | 
|  | float b = 2.0f; | 
|  | float c = 3.0f; | 
|  | float d = 4.0f; | 
|  | *out = ((float4) {a,b,c,d}); | 
|  | } | 
|  |  | 
|  | // CHECK: @test5 | 
|  | // CHECK: shufflevector {{.*}} <4 x i32> zeroinitializer | 
|  | // CHECK: fmul <4 x float> | 
|  | // CHECK: fmul <4 x float> | 
|  | // CHECK: shufflevector {{.*}} <4 x i32> zeroinitializer | 
|  | // CHECK: fmul <4 x float> | 
|  | void test5(float4 *out) { | 
|  | float a; | 
|  | float4 b; | 
|  |  | 
|  | a = 1.0f; | 
|  | b = a; | 
|  | b = b * 5.0f; | 
|  | b = 5.0f * b; | 
|  | b *= a; | 
|  |  | 
|  | *out = b; | 
|  | } | 
|  |  | 
|  | // CHECK: @test6 | 
|  | void test6(float4 *ap, float4 *bp, float c) { | 
|  | float4 a = *ap; | 
|  | float4 b = *bp; | 
|  |  | 
|  | // CHECK: fadd <4 x float> | 
|  | // CHECK: fsub <4 x float> | 
|  | // CHECK: fmul <4 x float> | 
|  | // CHECK: fdiv <4 x float> | 
|  | a = a + b; | 
|  | a = a - b; | 
|  | a = a * b; | 
|  | a = a / b; | 
|  |  | 
|  | // CHECK: fadd <4 x float> | 
|  | // CHECK: fsub <4 x float> | 
|  | // CHECK: fmul <4 x float> | 
|  | // CHECK: fdiv <4 x float> | 
|  | a = a + c; | 
|  | a = a - c; | 
|  | a = a * c; | 
|  | a = a / c; | 
|  |  | 
|  | // CHECK: fadd <4 x float> | 
|  | // CHECK: fsub <4 x float> | 
|  | // CHECK: fmul <4 x float> | 
|  | // CHECK: fdiv <4 x float> | 
|  | a += b; | 
|  | a -= b; | 
|  | a *= b; | 
|  | a /= b; | 
|  |  | 
|  | // CHECK: fadd <4 x float> | 
|  | // CHECK: fsub <4 x float> | 
|  | // CHECK: fmul <4 x float> | 
|  | // CHECK: fdiv <4 x float> | 
|  | a += c; | 
|  | a -= c; | 
|  | a *= c; | 
|  | a /= c; | 
|  |  | 
|  | // Vector comparisons can sometimes crash the x86 backend, reject them until | 
|  | // the implementation is stable. | 
|  | #if 0 | 
|  | int4 cmp; | 
|  | cmp = a < b; | 
|  | cmp = a <= b; | 
|  | cmp = a < b; | 
|  | cmp = a >= b; | 
|  | cmp = a == b; | 
|  | cmp = a != b; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // CHECK: @test7 | 
|  | void test7(int4 *ap, int4 *bp, int c) { | 
|  | int4 a = *ap; | 
|  | int4 b = *bp; | 
|  |  | 
|  | // CHECK: add <4 x i32> | 
|  | // CHECK: sub <4 x i32> | 
|  | // CHECK: mul <4 x i32> | 
|  | // CHECK: sdiv <4 x i32> | 
|  | // CHECK: srem <4 x i32> | 
|  | a = a + b; | 
|  | a = a - b; | 
|  | a = a * b; | 
|  | a = a / b; | 
|  | a = a % b; | 
|  |  | 
|  | // CHECK: add <4 x i32> | 
|  | // CHECK: sub <4 x i32> | 
|  | // CHECK: mul <4 x i32> | 
|  | // CHECK: sdiv <4 x i32> | 
|  | // CHECK: srem <4 x i32> | 
|  | a = a + c; | 
|  | a = a - c; | 
|  | a = a * c; | 
|  | a = a / c; | 
|  | a = a % c; | 
|  |  | 
|  | // CHECK: add <4 x i32> | 
|  | // CHECK: sub <4 x i32> | 
|  | // CHECK: mul <4 x i32> | 
|  | // CHECK: sdiv <4 x i32> | 
|  | // CHECK: srem <4 x i32> | 
|  | a += b; | 
|  | a -= b; | 
|  | a *= b; | 
|  | a /= b; | 
|  | a %= b; | 
|  |  | 
|  | // CHECK: add <4 x i32> | 
|  | // CHECK: sub <4 x i32> | 
|  | // CHECK: mul <4 x i32> | 
|  | // CHECK: sdiv <4 x i32> | 
|  | // CHECK: srem <4 x i32> | 
|  | a += c; | 
|  | a -= c; | 
|  | a *= c; | 
|  | a /= c; | 
|  | a %= c; | 
|  |  | 
|  |  | 
|  | // Vector comparisons. | 
|  | // CHECK: icmp slt | 
|  | // CHECK: icmp sle | 
|  | // CHECK: icmp sgt | 
|  | // CHECK: icmp sge | 
|  | // CHECK: icmp eq | 
|  | // CHECK: icmp ne | 
|  | int4 cmp; | 
|  | cmp = a < b; | 
|  | cmp = a <= b; | 
|  | cmp = a > b; | 
|  | cmp = a >= b; | 
|  | cmp = a == b; | 
|  | cmp = a != b; | 
|  | } | 
|  |  | 
|  | // CHECK: @test8 | 
|  | void test8(float4 *ap, float4 *bp, int c) { | 
|  | float4 a = *ap; | 
|  | float4 b = *bp; | 
|  |  | 
|  | // Vector comparisons. | 
|  | // CHECK: fcmp olt | 
|  | // CHECK: fcmp ole | 
|  | // CHECK: fcmp ogt | 
|  | // CHECK: fcmp oge | 
|  | // CHECK: fcmp oeq | 
|  | // CHECK: fcmp une | 
|  | int4 cmp; | 
|  | cmp = a < b; | 
|  | cmp = a <= b; | 
|  | cmp = a > b; | 
|  | cmp = a >= b; | 
|  | cmp = a == b; | 
|  | cmp = a != b; | 
|  | } | 
|  |  | 
|  | // CHECK: @test9 | 
|  | // CHECK: extractelement <4 x i32> | 
|  | int test9(int4 V) { | 
|  | return V.xy.x; | 
|  | } | 
|  |  | 
|  | // CHECK: @test10 | 
|  | // CHECK: add <4 x i32> | 
|  | // CHECK: extractelement <4 x i32> | 
|  | int test10(int4 V) { | 
|  | return (V+V).x; | 
|  | } | 
|  |  | 
|  | // CHECK: @test11 | 
|  | // CHECK: extractelement <4 x i32> | 
|  | int4 test11a(void); | 
|  | int test11(void) { | 
|  | return test11a().x; | 
|  | } | 
|  |  | 
|  | // CHECK: @test12 | 
|  | // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0> | 
|  | // CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 poison> | 
|  | // CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3> | 
|  | int4 test12(int4 V) { | 
|  | V.xyz = V.zyx; | 
|  | return V; | 
|  | } | 
|  |  | 
|  | // CHECK: @test13 | 
|  | // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0, i32 3> | 
|  | int4 test13(int4 *V) { | 
|  | return V->zyxw; | 
|  | } | 
|  |  | 
|  | // CHECK: @test14 | 
|  | void test14(uint4 *ap, uint4 *bp, unsigned c) { | 
|  | uint4 a = *ap; | 
|  | uint4 b = *bp; | 
|  | int4 d; | 
|  |  | 
|  | // CHECK: udiv <4 x i32> | 
|  | // CHECK: urem <4 x i32> | 
|  | a = a / b; | 
|  | a = a % b; | 
|  |  | 
|  | // CHECK: udiv <4 x i32> | 
|  | // CHECK: urem <4 x i32> | 
|  | a = a / c; | 
|  | a = a % c; | 
|  |  | 
|  | // CHECK: icmp ult | 
|  | // CHECK: icmp ule | 
|  | // CHECK: icmp ugt | 
|  | // CHECK: icmp uge | 
|  | // CHECK: icmp eq | 
|  | // CHECK: icmp ne | 
|  | d = a < b; | 
|  | d = a <= b; | 
|  | d = a > b; | 
|  | d = a >= b; | 
|  | d = a == b; | 
|  | d = a != b; | 
|  | } | 
|  |  | 
|  | // CHECK: @test15 | 
|  | int4 test15(uint4 V0) { | 
|  | // CHECK: icmp eq <4 x i32> | 
|  | int4 V = !V0; | 
|  | V = V && V; | 
|  | V = V || V; | 
|  | return V; | 
|  | } | 
|  |  | 
|  | // CHECK: @test16 | 
|  | void test16(float2 a, float2 b) { | 
|  | float2 t0 = (a + b) / 2; | 
|  | } | 
|  |  | 
|  | typedef char char16 __attribute__((ext_vector_type(16))); | 
|  |  | 
|  | // CHECK: @test17 | 
|  | void test17(void) { | 
|  | char16 valA; | 
|  | char valB; | 
|  | char valC; | 
|  | char16 destVal = valC ? valA : valB; | 
|  | } | 
|  |  | 
|  | typedef __attribute__(( ext_vector_type(16) )) float float16; | 
|  |  | 
|  | float16 vec16, vec16_2; | 
|  |  | 
|  | // CHECK: @test_rgba | 
|  | void test_rgba(void) { | 
|  | // CHECK: fadd <4 x float> | 
|  | vec4_2 = vec4.abgr + vec4; | 
|  |  | 
|  | // CHECK: shufflevector {{.*}} <i32 0, i32 1> | 
|  | vec2 = vec4.rg; | 
|  | // CHECK: shufflevector {{.*}} <i32 2, i32 3> | 
|  | vec2_2 = vec4.ba; | 
|  | // CHECK: extractelement {{.*}} 2 | 
|  | f = vec4.b; | 
|  | // CHECK: shufflevector {{.*}} <i32 2, i32 2, i32 2, i32 2> | 
|  | vec4_2 = vec4_2.bbbb; | 
|  |  | 
|  | // CHECK: insertelement {{.*}} 0 | 
|  | vec2.r = f; | 
|  | // CHECK: shufflevector {{.*}} <i32 1, i32 0> | 
|  | vec2.gr = vec2; | 
|  |  | 
|  | // CHECK: extractelement {{.*}} 0 | 
|  | f = vec4_2.rg.r; | 
|  | // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0> | 
|  | // CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 poison> | 
|  | // CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3> | 
|  | vec4.rgb = vec4.bgr; | 
|  |  | 
|  | // CHECK: extractelement {{.*}} 11 | 
|  | // CHECK: insertelement {{.*}} 2 | 
|  | vec4.b = vec16.sb; | 
|  | // CHECK: shufflevector {{.*}} <i32 10, i32 11, i32 12, i32 13> | 
|  | vec4_2 = vec16.sabcd; | 
|  | } |