1 // RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \ 2 // RUN: -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s 3 // RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \ 4 // RUN: -faltivec-src-compat=gcc -triple powerpc-unknown-unknown -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR 5 // RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \ 6 // RUN: -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s 7 // RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s 8 // RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s 9 10 // CHECK-LABEL: @ui8( 11 // CHECK: [[A_ADDR:%.*]] = alloca <16 x i8>, align 16 12 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <16 x i8>, align 16 13 // CHECK-NEXT: store <16 x i8> [[A:%.*]], <16 x i8>* [[A_ADDR]], align 16 14 // CHECK-NEXT: store <16 x i8> [[B:%.*]], <16 x i8>* [[B_ADDR]], align 16 15 // CHECK-NEXT: [[TMP0:%.*]] = load <16 x i8>, <16 x i8>* [[A_ADDR]], align 16 16 // CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[B_ADDR]], align 16 17 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequb.p(i32 2, <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) 18 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 19 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 20 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 21 // CHECK-NEXT: ret i32 [[COND]] 22 // 23 // ERROR: error: used type '__attribute__((__vector_size__(16 * sizeof(char)))) char' (vector of 16 'char' values) where arithmetic or pointer type is required 24 int ui8(vector unsigned char a, vector unsigned char b) { 25 return a == b ? 3 : 7; 26 } 27 28 // CHECK-LABEL: @si8( 29 // CHECK: [[A_ADDR:%.*]] = alloca <16 x i8>, align 16 30 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <16 x i8>, align 16 31 // CHECK-NEXT: store <16 x i8> [[A:%.*]], <16 x i8>* [[A_ADDR]], align 16 32 // CHECK-NEXT: store <16 x i8> [[B:%.*]], <16 x i8>* [[B_ADDR]], align 16 33 // CHECK-NEXT: [[TMP0:%.*]] = load <16 x i8>, <16 x i8>* [[A_ADDR]], align 16 34 // CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[B_ADDR]], align 16 35 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequb.p(i32 2, <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) 36 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 37 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 38 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 39 // CHECK-NEXT: ret i32 [[COND]] 40 // 41 // ERROR: error: used type '__attribute__((__vector_size__(16 * sizeof(char)))) char' (vector of 16 'char' values) where arithmetic or pointer type is required 42 int si8(vector signed char a, vector signed char b) { 43 return a == b ? 3 : 7; 44 } 45 46 // CHECK-LABEL: @ui16( 47 // CHECK: [[A_ADDR:%.*]] = alloca <8 x i16>, align 16 48 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <8 x i16>, align 16 49 // CHECK-NEXT: store <8 x i16> [[A:%.*]], <8 x i16>* [[A_ADDR]], align 16 50 // CHECK-NEXT: store <8 x i16> [[B:%.*]], <8 x i16>* [[B_ADDR]], align 16 51 // CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, <8 x i16>* [[A_ADDR]], align 16 52 // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[B_ADDR]], align 16 53 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequh.p(i32 2, <8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) 54 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 55 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 56 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 57 // CHECK-NEXT: ret i32 [[COND]] 58 // 59 // ERROR: error: used type '__attribute__((__vector_size__(8 * sizeof(short)))) short' (vector of 8 'short' values) where arithmetic or pointer type is required 60 int ui16(vector unsigned short a, vector unsigned short b) { 61 return a == b ? 3 : 7; 62 } 63 64 // CHECK-LABEL: @si16( 65 // CHECK: [[A_ADDR:%.*]] = alloca <8 x i16>, align 16 66 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <8 x i16>, align 16 67 // CHECK-NEXT: store <8 x i16> [[A:%.*]], <8 x i16>* [[A_ADDR]], align 16 68 // CHECK-NEXT: store <8 x i16> [[B:%.*]], <8 x i16>* [[B_ADDR]], align 16 69 // CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, <8 x i16>* [[A_ADDR]], align 16 70 // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[B_ADDR]], align 16 71 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequh.p(i32 2, <8 x i16> [[TMP0]], <8 x i16> [[TMP1]]) 72 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 73 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 74 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 75 // CHECK-NEXT: ret i32 [[COND]] 76 // 77 // ERROR: error: used type '__attribute__((__vector_size__(8 * sizeof(short)))) short' (vector of 8 'short' values) where arithmetic or pointer type is required 78 int si16(vector signed short a, vector signed short b) { 79 return a == b ? 3 : 7; 80 } 81 82 // CHECK-LABEL: @ui32( 83 // CHECK: [[A_ADDR:%.*]] = alloca <4 x i32>, align 16 84 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x i32>, align 16 85 // CHECK-NEXT: store <4 x i32> [[A:%.*]], <4 x i32>* [[A_ADDR]], align 16 86 // CHECK-NEXT: store <4 x i32> [[B:%.*]], <4 x i32>* [[B_ADDR]], align 16 87 // CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, <4 x i32>* [[A_ADDR]], align 16 88 // CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[B_ADDR]], align 16 89 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequw.p(i32 2, <4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) 90 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 91 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 92 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 93 // CHECK-NEXT: ret i32 [[COND]] 94 // 95 // ERROR: error: used type '__attribute__((__vector_size__(4 * sizeof(long)))) long' (vector of 4 'long' values) where arithmetic or pointer type is required 96 int ui32(vector unsigned int a, vector unsigned int b) { 97 return a == b ? 3 : 7; 98 } 99 100 // CHECK-LABEL: @si32( 101 // CHECK: [[A_ADDR:%.*]] = alloca <4 x i32>, align 16 102 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x i32>, align 16 103 // CHECK-NEXT: store <4 x i32> [[A:%.*]], <4 x i32>* [[A_ADDR]], align 16 104 // CHECK-NEXT: store <4 x i32> [[B:%.*]], <4 x i32>* [[B_ADDR]], align 16 105 // CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, <4 x i32>* [[A_ADDR]], align 16 106 // CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[B_ADDR]], align 16 107 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequw.p(i32 2, <4 x i32> [[TMP0]], <4 x i32> [[TMP1]]) 108 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 109 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 110 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 111 // CHECK-NEXT: ret i32 [[COND]] 112 // 113 // ERROR: error: used type '__attribute__((__vector_size__(4 * sizeof(long)))) long' (vector of 4 'long' values) where arithmetic or pointer type is required 114 int si32(vector signed int a, vector signed int b) { 115 return a == b ? 3 : 7; 116 } 117 118 // CHECK-LABEL: @si64( 119 // CHECK: [[A_ADDR:%.*]] = alloca <2 x i64>, align 16 120 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <2 x i64>, align 16 121 // CHECK-NEXT: store <2 x i64> [[A:%.*]], <2 x i64>* [[A_ADDR]], align 16 122 // CHECK-NEXT: store <2 x i64> [[B:%.*]], <2 x i64>* [[B_ADDR]], align 16 123 // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* [[A_ADDR]], align 16 124 // CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[B_ADDR]], align 16 125 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequd.p(i32 2, <2 x i64> [[TMP0]], <2 x i64> [[TMP1]]) 126 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 127 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 128 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 129 // CHECK-NEXT: ret i32 [[COND]] 130 // 131 // ERROR: error: used type '__attribute__((__vector_size__(2 * sizeof(long long)))) long long' (vector of 2 'long long' values) where arithmetic or pointer type is required 132 int si64(vector long long a, vector long long b) { 133 return a == b ? 3 : 7; 134 } 135 136 // CHECK-LABEL: @f32( 137 // CHECK: [[A_ADDR:%.*]] = alloca <4 x float>, align 16 138 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x float>, align 16 139 // CHECK-NEXT: store <4 x float> [[A:%.*]], <4 x float>* [[A_ADDR]], align 16 140 // CHECK-NEXT: store <4 x float> [[B:%.*]], <4 x float>* [[B_ADDR]], align 16 141 // CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, <4 x float>* [[A_ADDR]], align 16 142 // CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[B_ADDR]], align 16 143 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpeqfp.p(i32 2, <4 x float> [[TMP0]], <4 x float> [[TMP1]]) 144 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 145 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 146 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 147 // CHECK-NEXT: ret i32 [[COND]] 148 // 149 // ERROR: error: used type '__attribute__((__vector_size__(4 * sizeof(long)))) long' (vector of 4 'long' values) where arithmetic or pointer type is required 150 int f32(vector float a, vector float b) { 151 return a == b ? 3 : 7; 152 } 153 154 // CHECK-LABEL: @f64( 155 // CHECK: [[A_ADDR:%.*]] = alloca <2 x double>, align 16 156 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca <2 x double>, align 16 157 // CHECK-NEXT: store <2 x double> [[A:%.*]], <2 x double>* [[A_ADDR]], align 16 158 // CHECK-NEXT: store <2 x double> [[B:%.*]], <2 x double>* [[B_ADDR]], align 16 159 // CHECK-NEXT: [[TMP0:%.*]] = load <2 x double>, <2 x double>* [[A_ADDR]], align 16 160 // CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, <2 x double>* [[B_ADDR]], align 16 161 // CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.vsx.xvcmpeqdp.p(i32 2, <2 x double> [[TMP0]], <2 x double> [[TMP1]]) 162 // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0 163 // CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64 164 // CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7 165 // CHECK-NEXT: ret i32 [[COND]] 166 // 167 // ERROR: error: used type '__attribute__((__vector_size__(2 * sizeof(long long)))) long long' (vector of 2 'long long' values) where arithmetic or pointer type is required 168 int f64(vector double a, vector double b) { 169 return a == b ? 3 : 7; 170 } 171