brintos

brintos / llvm-project-archived public Read only

0
0
Text · 67.3 KiB · 2df485f Raw
1395 lines · c
1// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s2 3typedef _Float16 half;4 5typedef half half2 __attribute__((ext_vector_type(2)));6typedef float float2 __attribute__((ext_vector_type(2)));7typedef float float4 __attribute__((ext_vector_type(4)));8typedef short int si8 __attribute__((ext_vector_type(8)));9typedef int int4 __attribute__((ext_vector_type(4)));10typedef unsigned int u4 __attribute__((ext_vector_type(4)));11typedef double double2 __attribute__((ext_vector_type(2)));12typedef double double3 __attribute__((ext_vector_type(3)));13 14__attribute__((address_space(1))) int int_as_one;15typedef int bar;16bar b;17 18struct StructWithBitfield {19  int i : 5;20  short s : 3;21  char c: 2;22  long long int lli : 3;23};24 25void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,26                                  float4 vf1, float4 vf2, si8 vi1, si8 vi2,27                                  long long int i1, long long int i2, short si,28                                  _BitInt(31) bi1, _BitInt(31) bi2, int i,29                                  char ci) {30  // CHECK-LABEL: define void @test_builtin_elementwise_abs(31  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 432  // CHECK-NEXT:  call float @llvm.fabs.f32(float [[F1]])33  f2 = __builtin_elementwise_abs(f1);34 35  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 836  // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]])37  d2 = __builtin_elementwise_abs(d1);38 39  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 1640  // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]])41  vf2 = __builtin_elementwise_abs(vf1);42 43  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 844  // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false)45  i2 = __builtin_elementwise_abs(i1);46 47  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 848  // CHECK:      [[S1:%.+]] = trunc i64 [[I1]] to i1649  // CHECK-NEXT: call i16 @llvm.abs.i16(i16 [[S1]], i1 false)50  i1 = __builtin_elementwise_abs((short)i1);51 52  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 1653  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false)54  vi2 = __builtin_elementwise_abs(vi1);55 56  // CHECK:      [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 1657  // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false)58  const si8 cvi2 = vi2;59  vi2 = __builtin_elementwise_abs(cvi2);60 61  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 462  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i3163  // CHECK-NEXT: call i31 @llvm.abs.i31(i31 [[LOADEDV]], i1 false)64  bi2 = __builtin_elementwise_abs(bi1);65 66  // CHECK:      [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 467  // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false)68  b = __builtin_elementwise_abs(int_as_one);69 70  // CHECK:   store i32 %elt.abs11, ptr @b, align 471  b = __builtin_elementwise_abs(-10);72 73  // CHECK:      [[SI:%.+]] = load i16, ptr %si.addr, align 274  // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.abs.i16(i16 [[SI]], i1 false)75  si = __builtin_elementwise_abs(si);76 77  struct StructWithBitfield t;78 79  // CHECK:      [[BFLOAD:%.+]] = load i16, ptr %t, align 880  // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 1181  // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 1182  // CHECK-NEXT: [[BFCAST:%.+]] = sext i16 [[BFASHR]] to i3283  // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[BFCAST]], i1 false)84  i = __builtin_elementwise_abs(t.i);85 86  // CHECK:      [[BFLOAD:%.+]] = load i16, ptr %t, align 887  // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 888  // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 1389  // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.abs.i16(i16 [[BFASHR]], i1 false)90  si = __builtin_elementwise_abs(t.s);91 92  // CHECK:      [[BFLOAD:%.+]] = load i16, ptr %t, align 893  // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 694  // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 1495  // CHECK-NEXT: [[BFCAST:%.+]] = trunc i16 [[BFASHR]] to i896  // CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.abs.i8(i8 [[BFCAST]], i1 false)97  ci = __builtin_elementwise_abs(t.c);98 99  // CHECK:      [[BFLOAD:%.+]] = load i16, ptr %t, align 8100  // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 3101  // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 13102  // CHECK-NEXT: [[BFCAST:%.+]] = sext i16 [[BFASHR]] to i64103  // CHECK-NEXT: [[RES:%.+]] = call i64 @llvm.abs.i64(i64 [[BFCAST]], i1 false)104  i1 = __builtin_elementwise_abs(t.lli);105}106 107void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2,108                                      float4 vf1, float4 vf2, long long int i1,109                                      long long int i2, si8 vi1, si8 vi2,110                                      unsigned u1, unsigned u2, u4 vu1, u4 vu2,111                                      _BitInt(31) bi1, _BitInt(31) bi2,112                                      unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2,113                                      char c1, char c2, unsigned char uc1,114                                      unsigned char uc2, short s1, short s2,115                                      unsigned short us1, unsigned short us2) {116  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8117  // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8118  // CHECK-NEXT: call i64 @llvm.sadd.sat.i64(i64 [[I1]], i64 [[I2]])119  i1 = __builtin_elementwise_add_sat(i1, i2);120 121  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8122  // CHECK-NEXT: call i64 @llvm.sadd.sat.i64(i64 [[I1]], i64 10)123  i1 = __builtin_elementwise_add_sat(i1, 10ll);124 125  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16126  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16127  // CHECK-NEXT: call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])128  vi1 = __builtin_elementwise_add_sat(vi1, vi2);129 130  // CHECK:      [[U1:%.+]] = load i32, ptr %u1.addr, align 4131  // CHECK-NEXT: [[U2:%.+]] = load i32, ptr %u2.addr, align 4132  // CHECK-NEXT: call i32 @llvm.uadd.sat.i32(i32 [[U1]], i32 [[U2]])133  u1 = __builtin_elementwise_add_sat(u1, u2);134 135  // CHECK:      [[VU1:%.+]] = load <4 x i32>, ptr %vu1.addr, align 16136  // CHECK-NEXT: [[VU2:%.+]] = load <4 x i32>, ptr %vu2.addr, align 16137  // CHECK-NEXT: call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])138  vu1 = __builtin_elementwise_add_sat(vu1, vu2);139 140  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4141  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31142  // CHECK-NEXT: [[BI2:%.+]] = load i32, ptr %bi2.addr, align 4143  // CHECK-NEXT: [[LOADEDV1:%.+]] = trunc i32 [[BI2]] to i31144  // CHECK-NEXT: call i31 @llvm.sadd.sat.i31(i31 [[LOADEDV]], i31 [[LOADEDV1]])145  bi1 = __builtin_elementwise_add_sat(bi1, bi2);146 147  // CHECK:      [[BU1:%.+]] = load i64, ptr %bu1.addr, align 8148  // CHECK-NEXT: [[LOADEDV2:%.+]] = trunc i64 [[BU1]] to i55149  // CHECK-NEXT: [[BU2:%.+]] = load i64, ptr %bu2.addr, align 8150  // CHECK-NEXT: [[LOADEDV3:%.+]] = trunc i64 [[BU2]] to i55151  // CHECK-NEXT: call i55 @llvm.uadd.sat.i55(i55 [[LOADEDV2]], i55 [[LOADEDV3]])152  bu1 = __builtin_elementwise_add_sat(bu1, bu2);153 154  // CHECK:      [[IAS1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4155  // CHECK-NEXT: [[B:%.+]] = load i32, ptr @b, align 4156  // CHECK-NEXT: call i32 @llvm.sadd.sat.i32(i32 [[IAS1]], i32 [[B]])157  int_as_one = __builtin_elementwise_add_sat(int_as_one, b);158 159  // CHECK: store i64 98, ptr %i1.addr, align 8160  i1 = __builtin_elementwise_add_sat(1, 'a');161 162  // CHECK:      [[C1:%.+]] = load i8, ptr %c1.addr, align 1163  // CHECK-NEXT: [[C2:%.+]] = load i8, ptr %c2.addr, align 1164  // CHECK-NEXT: call i8 @llvm.sadd.sat.i8(i8 [[C1]], i8 [[C2]])165  c1 = __builtin_elementwise_add_sat(c1, c2);166 167  // CHECK:      [[UC1:%.+]] = load i8, ptr %uc1.addr, align 1168  // CHECK-NEXT: [[UC2:%.+]] = load i8, ptr %uc2.addr, align 1169  // CHECK-NEXT: call i8 @llvm.uadd.sat.i8(i8 [[UC1]], i8 [[UC2]])170  uc1 = __builtin_elementwise_add_sat(uc1, uc2);171 172  // CHECK:      [[S1:%.+]] = load i16, ptr %s1.addr, align 2173  // CHECK-NEXT: [[S2:%.+]] = load i16, ptr %s2.addr, align 2174  // CHECK-NEXT: call i16 @llvm.sadd.sat.i16(i16 [[S1]], i16 [[S2]])175  s1 = __builtin_elementwise_add_sat(s1, s2);176 177  // CHECK:      [[S1:%.+]] = load i16, ptr %s1.addr, align 2178  // CHECK:      [[I1:%.+]] = sext i16 [[S1]] to i32179  // CHECK-NEXT: [[S2:%.+]] = load i16, ptr %s2.addr, align 2180  // CHECK:      [[I2:%.+]] = sext i16 [[S2]] to i32181  // CHECK-NEXT: call i32 @llvm.sadd.sat.i32(i32 [[I1]], i32 [[I2]])182  s1 = __builtin_elementwise_add_sat((int)s1, (int)s2);183 184  // CHECK:      [[US1:%.+]] = load i16, ptr %us1.addr, align 2185  // CHECK-NEXT: [[US2:%.+]] = load i16, ptr %us2.addr, align 2186  // CHECK-NEXT: call i16 @llvm.uadd.sat.i16(i16 [[US1]], i16 [[US2]])187  us1 = __builtin_elementwise_add_sat(us1, us2);188}189 190void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2,191                                      float4 vf1, float4 vf2, long long int i1,192                                      long long int i2, si8 vi1, si8 vi2,193                                      unsigned u1, unsigned u2, u4 vu1, u4 vu2,194                                      _BitInt(31) bi1, _BitInt(31) bi2,195                                      unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2,196                                      char c1, char c2, unsigned char uc1,197                                      unsigned char uc2, short s1, short s2,198                                      unsigned short us1, unsigned short us2) {199  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8200  // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8201  // CHECK-NEXT: call i64 @llvm.ssub.sat.i64(i64 [[I1]], i64 [[I2]])202  i1 = __builtin_elementwise_sub_sat(i1, i2);203 204  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8205  // CHECK-NEXT: call i64 @llvm.ssub.sat.i64(i64 [[I1]], i64 10)206  i1 = __builtin_elementwise_sub_sat(i1, 10ll);207 208  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16209  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16210  // CHECK-NEXT: call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])211  vi1 = __builtin_elementwise_sub_sat(vi1, vi2);212 213  // CHECK:      [[U1:%.+]] = load i32, ptr %u1.addr, align 4214  // CHECK-NEXT: [[U2:%.+]] = load i32, ptr %u2.addr, align 4215  // CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 [[U1]], i32 [[U2]])216  u1 = __builtin_elementwise_sub_sat(u1, u2);217 218  // CHECK:      [[VU1:%.+]] = load <4 x i32>, ptr %vu1.addr, align 16219  // CHECK-NEXT: [[VU2:%.+]] = load <4 x i32>, ptr %vu2.addr, align 16220  // CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])221  vu1 = __builtin_elementwise_sub_sat(vu1, vu2);222 223  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4224  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31225  // CHECK-NEXT: [[BI2:%.+]] = load i32, ptr %bi2.addr, align 4226  // CHECK-NEXT: [[LOADEDV1:%.+]] = trunc i32 [[BI2]] to i31227  // CHECK-NEXT: call i31 @llvm.ssub.sat.i31(i31 [[LOADEDV]], i31 [[LOADEDV1]])228  bi1 = __builtin_elementwise_sub_sat(bi1, bi2);229 230  // CHECK:      [[BU1:%.+]] = load i64, ptr %bu1.addr, align 8231  // CHECK-NEXT: [[LOADEDV2:%.+]] = trunc i64 [[BU1]] to i55232  // CHECK-NEXT: [[BU2:%.+]] = load i64, ptr %bu2.addr, align 8233  // CHECK-NEXT: [[LOADEDV3:%.+]] = trunc i64 [[BU2]] to i55234  // CHECK-NEXT: call i55 @llvm.usub.sat.i55(i55 [[LOADEDV2]], i55 [[LOADEDV3]])235  bu1 = __builtin_elementwise_sub_sat(bu1, bu2);236 237  // CHECK:      [[IAS1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4238  // CHECK-NEXT: [[B:%.+]] = load i32, ptr @b, align 4239  // CHECK-NEXT: call i32 @llvm.ssub.sat.i32(i32 [[IAS1]], i32 [[B]])240  int_as_one = __builtin_elementwise_sub_sat(int_as_one, b);241 242  // CHECK: store i64 -96, ptr %i1.addr, align 8243  i1 = __builtin_elementwise_sub_sat(1, 'a');244 245  // CHECK:      [[C1:%.+]] = load i8, ptr %c1.addr, align 1246  // CHECK-NEXT: [[C2:%.+]] = load i8, ptr %c2.addr, align 1247  // CHECK-NEXT: call i8 @llvm.ssub.sat.i8(i8 [[C1]], i8 [[C2]])248  c1 = __builtin_elementwise_sub_sat(c1, c2);249 250  // CHECK:      [[UC1:%.+]] = load i8, ptr %uc1.addr, align 1251  // CHECK-NEXT: [[UC2:%.+]] = load i8, ptr %uc2.addr, align 1252  // CHECK-NEXT: call i8 @llvm.usub.sat.i8(i8 [[UC1]], i8 [[UC2]])253  uc1 = __builtin_elementwise_sub_sat(uc1, uc2);254 255  // CHECK:      [[S1:%.+]] = load i16, ptr %s1.addr, align 2256  // CHECK-NEXT: [[S2:%.+]] = load i16, ptr %s2.addr, align 2257  // CHECK-NEXT: call i16 @llvm.ssub.sat.i16(i16 [[S1]], i16 [[S2]])258  s1 = __builtin_elementwise_sub_sat(s1, s2);259 260  // CHECK:      [[US1:%.+]] = load i16, ptr %us1.addr, align 2261  // CHECK-NEXT: [[US2:%.+]] = load i16, ptr %us2.addr, align 2262  // CHECK-NEXT: call i16 @llvm.usub.sat.i16(i16 [[US1]], i16 [[US2]])263  us1 = __builtin_elementwise_sub_sat(us1, us2);264}265 266void test_builtin_elementwise_maximum(float f1, float f2, double d1, double d2,267                                      float4 vf1, float4 vf2, long long int i1,268                                      long long int i2, si8 vi1, si8 vi2,269                                      unsigned u1, unsigned u2, u4 vu1, u4 vu2,270                                      _BitInt(31) bi1, _BitInt(31) bi2,271                                      unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2) {272  // CHECK-LABEL: define void @test_builtin_elementwise_maximum(273  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4274  // CHECK-NEXT: [[F2:%.+]] = load float, ptr %f2.addr, align 4275  // CHECK-NEXT:  call float @llvm.maximum.f32(float [[F1]], float [[F2]])276  f1 = __builtin_elementwise_maximum(f1, f2);277 278  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8279  // CHECK-NEXT: [[D2:%.+]] = load double, ptr %d2.addr, align 8280  // CHECK-NEXT: call double @llvm.maximum.f64(double [[D1]], double [[D2]])281  d1 = __builtin_elementwise_maximum(d1, d2);282 283  // CHECK:      [[D2:%.+]] = load double, ptr %d2.addr, align 8284  // CHECK-NEXT: call double @llvm.maximum.f64(double 2.000000e+01, double [[D2]])285  d1 = __builtin_elementwise_maximum(20.0, d2);286 287  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16288  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16289  // CHECK-NEXT: call <4 x float> @llvm.maximum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])290  vf1 = __builtin_elementwise_maximum(vf1, vf2);291 292  // CHECK:      [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16293  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16294  // CHECK-NEXT: call <4 x float> @llvm.maximum.v4f32(<4 x float> [[CVF1]], <4 x float> [[VF2]])295  const float4 cvf1 = vf1;296  vf1 = __builtin_elementwise_maximum(cvf1, vf2);297 298  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16299  // CHECK-NEXT: [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16300  // CHECK-NEXT: call <4 x float> @llvm.maximum.v4f32(<4 x float> [[VF2]], <4 x float> [[CVF1]])301  vf1 = __builtin_elementwise_maximum(vf2, cvf1);302}303 304void test_builtin_elementwise_minimum(float f1, float f2, double d1, double d2,305                                      float4 vf1, float4 vf2, long long int i1,306                                      long long int i2, si8 vi1, si8 vi2,307                                      unsigned u1, unsigned u2, u4 vu1, u4 vu2,308                                      _BitInt(31) bi1, _BitInt(31) bi2,309                                      unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2) {310  // CHECK-LABEL: define void @test_builtin_elementwise_minimum(311  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4312  // CHECK-NEXT: [[F2:%.+]] = load float, ptr %f2.addr, align 4313  // CHECK-NEXT:  call float @llvm.minimum.f32(float [[F1]], float [[F2]])314  f1 = __builtin_elementwise_minimum(f1, f2);315 316  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8317  // CHECK-NEXT: [[D2:%.+]] = load double, ptr %d2.addr, align 8318  // CHECK-NEXT: call double @llvm.minimum.f64(double [[D1]], double [[D2]])319  d1 = __builtin_elementwise_minimum(d1, d2);320 321  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8322  // CHECK-NEXT: call double @llvm.minimum.f64(double [[D1]], double 2.000000e+00)323  d1 = __builtin_elementwise_minimum(d1, 2.0);324 325  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16326  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16327  // CHECK-NEXT: call <4 x float> @llvm.minimum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])328  vf1 = __builtin_elementwise_minimum(vf1, vf2);329 330  // CHECK:      [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16331  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16332  // CHECK-NEXT: call <4 x float> @llvm.minimum.v4f32(<4 x float> [[CVF1]], <4 x float> [[VF2]])333  const float4 cvf1 = vf1;334  vf1 = __builtin_elementwise_minimum(cvf1, vf2);335 336  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16337  // CHECK-NEXT: [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16338  // CHECK-NEXT: call <4 x float> @llvm.minimum.v4f32(<4 x float> [[VF2]], <4 x float> [[CVF1]])339  vf1 = __builtin_elementwise_minimum(vf2, cvf1);340}341 342void test_builtin_elementwise_max(float f1, float f2, double d1, double d2,343                                  float4 vf1, float4 vf2, long long int i1,344                                  long long int i2, si8 vi1, si8 vi2,345                                  unsigned u1, unsigned u2, u4 vu1, u4 vu2,346                                  _BitInt(31) bi1, _BitInt(31) bi2,347                                  unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2) {348  // CHECK-LABEL: define void @test_builtin_elementwise_max(349  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4350  // CHECK-NEXT: [[F2:%.+]] = load float, ptr %f2.addr, align 4351  // CHECK-NEXT:  call float @llvm.maxnum.f32(float [[F1]], float [[F2]])352  f1 = __builtin_elementwise_max(f1, f2);353 354  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8355  // CHECK-NEXT: [[D2:%.+]] = load double, ptr %d2.addr, align 8356  // CHECK-NEXT: call double @llvm.maxnum.f64(double [[D1]], double [[D2]])357  d1 = __builtin_elementwise_max(d1, d2);358 359  // CHECK:      [[D2:%.+]] = load double, ptr %d2.addr, align 8360  // CHECK-NEXT: call double @llvm.maxnum.f64(double 2.000000e+01, double [[D2]])361  d1 = __builtin_elementwise_max(20.0, d2);362 363  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16364  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16365  // CHECK-NEXT: call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])366  vf1 = __builtin_elementwise_max(vf1, vf2);367 368  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8369  // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8370  // CHECK-NEXT: call i64 @llvm.smax.i64(i64 [[I1]], i64 [[I2]])371  i1 = __builtin_elementwise_max(i1, i2);372 373  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8374  // CHECK-NEXT: call i64 @llvm.smax.i64(i64 [[I1]], i64 10)375  i1 = __builtin_elementwise_max(i1, 10ll);376 377  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16378  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16379  // CHECK-NEXT: call <8 x i16> @llvm.smax.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])380  vi1 = __builtin_elementwise_max(vi1, vi2);381 382  // CHECK:      [[U1:%.+]] = load i32, ptr %u1.addr, align 4383  // CHECK-NEXT: [[U2:%.+]] = load i32, ptr %u2.addr, align 4384  // CHECK-NEXT: call i32 @llvm.umax.i32(i32 [[U1]], i32 [[U2]])385  u1 = __builtin_elementwise_max(u1, u2);386 387  // CHECK:      [[VU1:%.+]] = load <4 x i32>, ptr %vu1.addr, align 16388  // CHECK-NEXT: [[VU2:%.+]] = load <4 x i32>, ptr %vu2.addr, align 16389  // CHECK-NEXT: call <4 x i32> @llvm.umax.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])390  vu1 = __builtin_elementwise_max(vu1, vu2);391 392  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4393  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31394  // CHECK-NEXT: [[BI2:%.+]] = load i32, ptr %bi2.addr, align 4395  // CHECK-NEXT: [[LOADEDV1:%.+]] = trunc i32 [[BI2]] to i31396  // CHECK-NEXT: call i31 @llvm.smax.i31(i31 [[LOADEDV]], i31 [[LOADEDV1]])397  bi1 = __builtin_elementwise_max(bi1, bi2);398 399  // CHECK:      [[BU1:%.+]] = load i64, ptr %bu1.addr, align 8400  // CHECK-NEXT: [[LOADEDV2:%.+]] = trunc i64 [[BU1]] to i55401  // CHECK-NEXT: [[BU2:%.+]] = load i64, ptr %bu2.addr, align 8402  // CHECK-NEXT: [[LOADEDV3:%.+]] = trunc i64 [[BU2]] to i55403  // CHECK-NEXT: call i55 @llvm.umax.i55(i55 [[LOADEDV2]], i55 [[LOADEDV3]])404  bu1 = __builtin_elementwise_max(bu1, bu2);405 406  // CHECK:      [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16407  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16408  // CHECK-NEXT: call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[CVF1]], <4 x float> [[VF2]])409  const float4 cvf1 = vf1;410  vf1 = __builtin_elementwise_max(cvf1, vf2);411 412  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16413  // CHECK-NEXT: [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16414  // CHECK-NEXT: call <4 x float> @llvm.maxnum.v4f32(<4 x float> [[VF2]], <4 x float> [[CVF1]])415  vf1 = __builtin_elementwise_max(vf2, cvf1);416 417  // CHECK:      [[IAS1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4418  // CHECK-NEXT: [[B:%.+]] = load i32, ptr @b, align 4419  // CHECK-NEXT: call i32 @llvm.smax.i32(i32 [[IAS1]], i32 [[B]])420  int_as_one = __builtin_elementwise_max(int_as_one, b);421 422  // CHECK: store i64 97, ptr [[I1:%.+]], align 8423  i1 = __builtin_elementwise_max(1, 'a');424}425 426void test_builtin_elementwise_min(float f1, float f2, double d1, double d2,427                                  float4 vf1, float4 vf2, long long int i1,428                                  long long int i2, si8 vi1, si8 vi2,429                                  unsigned u1, unsigned u2, u4 vu1, u4 vu2,430                                  _BitInt(31) bi1, _BitInt(31) bi2,431                                  unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2) {432  // CHECK-LABEL: define void @test_builtin_elementwise_min(433  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4434  // CHECK-NEXT: [[F2:%.+]] = load float, ptr %f2.addr, align 4435  // CHECK-NEXT:  call float @llvm.minnum.f32(float [[F1]], float [[F2]])436  f1 = __builtin_elementwise_min(f1, f2);437 438  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8439  // CHECK-NEXT: [[D2:%.+]] = load double, ptr %d2.addr, align 8440  // CHECK-NEXT: call double @llvm.minnum.f64(double [[D1]], double [[D2]])441  d1 = __builtin_elementwise_min(d1, d2);442 443  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8444  // CHECK-NEXT: call double @llvm.minnum.f64(double [[D1]], double 2.000000e+00)445  d1 = __builtin_elementwise_min(d1, 2.0);446 447  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16448  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16449  // CHECK-NEXT: call <4 x float> @llvm.minnum.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])450  vf1 = __builtin_elementwise_min(vf1, vf2);451 452  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8453  // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8454  // CHECK-NEXT: call i64 @llvm.smin.i64(i64 [[I1]], i64 [[I2]])455  i1 = __builtin_elementwise_min(i1, i2);456 457  // CHECK:      [[I2:%.+]] = load i64, ptr %i2.addr, align 8458  // CHECK-NEXT: call i64 @llvm.smin.i64(i64 -11, i64 [[I2]])459  i1 = __builtin_elementwise_min(-11ll, i2);460 461  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8462  // CHECK:      [[S1:%.+]] = trunc i64 [[I1]] to i16463  // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8464  // CHECK:      [[S2:%.+]] = trunc i64 [[I2]] to i16465  // CHECK-NEXT: call i16 @llvm.smin.i16(i16 [[S1]], i16 [[S2]])466  i1 = __builtin_elementwise_min((short)i1, (short)i2);467 468  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16469  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16470  // CHECK-NEXT: call <8 x i16> @llvm.smin.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]])471  vi1 = __builtin_elementwise_min(vi1, vi2);472 473  // CHECK:      [[U1:%.+]] = load i32, ptr %u1.addr, align 4474  // CHECK-NEXT: [[U2:%.+]] = load i32, ptr %u2.addr, align 4475  // CHECK-NEXT: call i32 @llvm.umin.i32(i32 [[U1]], i32 [[U2]])476  u1 = __builtin_elementwise_min(u1, u2);477 478  // CHECK:      [[VU1:%.+]] = load <4 x i32>, ptr %vu1.addr, align 16479  // CHECK-NEXT: [[VU2:%.+]] = load <4 x i32>, ptr %vu2.addr, align 16480  // CHECK-NEXT: call <4 x i32> @llvm.umin.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]])481  vu1 = __builtin_elementwise_min(vu1, vu2);482 483  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4484  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31485  // CHECK-NEXT: [[BI2:%.+]] = load i32, ptr %bi2.addr, align 4486  // CHECK-NEXT: [[LOADEDV1:%.+]] = trunc i32 [[BI2]] to i31487  // CHECK-NEXT: call i31 @llvm.smin.i31(i31 [[LOADEDV]], i31 [[LOADEDV1]])488  bi1 = __builtin_elementwise_min(bi1, bi2);489 490  // CHECK:      [[BU1:%.+]] = load i64, ptr %bu1.addr, align 8491  // CHECK-NEXT: [[LOADEDV2:%.+]] = trunc i64 [[BU1]] to i55492  // CHECK-NEXT: [[BU2:%.+]] = load i64, ptr %bu2.addr, align 8493  // CHECK-NEXT: [[LOADEDV3:%.+]] = trunc i64 [[BU2]] to i55494  // CHECK-NEXT: call i55 @llvm.umin.i55(i55 [[LOADEDV2]], i55 [[LOADEDV3]])495  bu1 = __builtin_elementwise_min(bu1, bu2);496 497  // CHECK:      [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16498  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16499  // CHECK-NEXT: call <4 x float> @llvm.minnum.v4f32(<4 x float> [[CVF1]], <4 x float> [[VF2]])500  const float4 cvf1 = vf1;501  vf1 = __builtin_elementwise_min(cvf1, vf2);502 503  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16504  // CHECK-NEXT: [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 16505  // CHECK-NEXT: call <4 x float> @llvm.minnum.v4f32(<4 x float> [[VF2]], <4 x float> [[CVF1]])506  vf1 = __builtin_elementwise_min(vf2, cvf1);507 508  // CHECK:      [[IAS1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4509  // CHECK-NEXT: [[B:%.+]] = load i32, ptr @b, align 4510  // CHECK-NEXT: call i32 @llvm.smin.i32(i32 [[IAS1]], i32 [[B]])511  int_as_one = __builtin_elementwise_min(int_as_one, b);512 513  // CHECK: store i64 2, ptr [[I1:%.+]], align 8514  i1 = __builtin_elementwise_min(2, 'b');515}516 517void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2,518                                  long long int i1, long long int i2, short si,519                                  _BitInt(31) bi1, _BitInt(31) bi2,520                                  char ci) {521  522 523  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8524  // CHECK-NEXT: call i64 @llvm.bitreverse.i64(i64 [[I1]])525  i2 = __builtin_elementwise_bitreverse(i1);526 527  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16528  // CHECK-NEXT: call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> [[VI1]])529  vi2 = __builtin_elementwise_bitreverse(vi1);530 531  // CHECK:      [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 16532  // CHECK-NEXT: call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> [[CVI2]])533  const si8 cvi2 = vi2;534  vi2 = __builtin_elementwise_bitreverse(cvi2);535 536  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4537  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31538  // CHECK-NEXT: call i31 @llvm.bitreverse.i31(i31 [[LOADEDV]])539  bi2 = __builtin_elementwise_bitreverse(bi1);540 541  // CHECK:      [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4542  // CHECK-NEXT: call i32 @llvm.bitreverse.i32(i32 [[IA1]])543  b = __builtin_elementwise_bitreverse(int_as_one);544 545  // CHECK:      store i32 1879048191, ptr @b, align 4546  b = __builtin_elementwise_bitreverse(-10);547 548  // CHECK:      [[SI:%.+]] = load i16, ptr %si.addr, align 2549  // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.bitreverse.i16(i16 [[SI]])550  si = __builtin_elementwise_bitreverse(si);551 552  // CHECK:      store i16 28671, ptr %si.addr, align 2553  si = __builtin_elementwise_bitreverse((short)-10);554 555  // CHECK:      store i16 28671, ptr %si.addr, align 2556  si = __builtin_elementwise_bitreverse((unsigned short)-10);557 558  // CHECK:      [[CI:%.+]] = load i8, ptr %ci.addr, align 1559  // CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.bitreverse.i8(i8 [[CI]])560  ci = __builtin_elementwise_bitreverse(ci);561 562  // CHECK:      store i8 111, ptr %ci.addr, align 1563  ci = __builtin_elementwise_bitreverse((unsigned char)-10);564 565  // CHECK:      store i8 111, ptr %ci.addr, align 1566  ci = __builtin_elementwise_bitreverse((char)-10);567}568 569void test_builtin_elementwise_ceil(float f1, float f2, double d1, double d2,570                                   float4 vf1, float4 vf2) {571  // CHECK-LABEL: define void @test_builtin_elementwise_ceil(572  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4573  // CHECK-NEXT:  call float @llvm.ceil.f32(float [[F1]])574  f2 = __builtin_elementwise_ceil(f1);575 576  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8577  // CHECK-NEXT: call double @llvm.ceil.f64(double [[D1]])578  d2 = __builtin_elementwise_ceil(d1);579 580  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16581  // CHECK-NEXT: call <4 x float> @llvm.ceil.v4f32(<4 x float> [[VF1]])582  vf2 = __builtin_elementwise_ceil(vf1);583}584 585void test_builtin_elementwise_acos(float f1, float f2, double d1, double d2,586                                  float4 vf1, float4 vf2) {587  // CHECK-LABEL: define void @test_builtin_elementwise_acos(588  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4589  // CHECK-NEXT:  call float @llvm.acos.f32(float [[F1]])590  f2 = __builtin_elementwise_acos(f1);591 592  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8593  // CHECK-NEXT: call double @llvm.acos.f64(double [[D1]])594  d2 = __builtin_elementwise_acos(d1);595 596  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16597  // CHECK-NEXT: call <4 x float> @llvm.acos.v4f32(<4 x float> [[VF1]])598  vf2 = __builtin_elementwise_acos(vf1);599}600 601void test_builtin_elementwise_asin(float f1, float f2, double d1, double d2,602                                  float4 vf1, float4 vf2) {603  // CHECK-LABEL: define void @test_builtin_elementwise_asin(604  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4605  // CHECK-NEXT:  call float @llvm.asin.f32(float [[F1]])606  f2 = __builtin_elementwise_asin(f1);607 608  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8609  // CHECK-NEXT: call double @llvm.asin.f64(double [[D1]])610  d2 = __builtin_elementwise_asin(d1);611 612  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16613  // CHECK-NEXT: call <4 x float> @llvm.asin.v4f32(<4 x float> [[VF1]])614  vf2 = __builtin_elementwise_asin(vf1);615}616 617void test_builtin_elementwise_atan(float f1, float f2, double d1, double d2,618                                  float4 vf1, float4 vf2) {619  // CHECK-LABEL: define void @test_builtin_elementwise_atan(620  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4621  // CHECK-NEXT:  call float @llvm.atan.f32(float [[F1]])622  f2 = __builtin_elementwise_atan(f1);623 624  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8625  // CHECK-NEXT: call double @llvm.atan.f64(double [[D1]])626  d2 = __builtin_elementwise_atan(d1);627 628  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16629  // CHECK-NEXT: call <4 x float> @llvm.atan.v4f32(<4 x float> [[VF1]])630  vf2 = __builtin_elementwise_atan(vf1);631}632 633void test_builtin_elementwise_atan2(float f1, float f2, float f3, double d1,634                                    double d2, double d3, float4 vf1,635                                    float4 vf2, float4 vf3) {636  // CHECK-LABEL: define void @test_builtin_elementwise_atan2(637  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4638  // CHECK-NEXT: [[F2:%.+]] = load float, ptr %f2.addr, align 4639  // CHECK-NEXT: call float @llvm.atan2.f32(float [[F1]], float [[F2]])640  f3 = __builtin_elementwise_atan2(f1, f2);641 642  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8643  // CHECK-NEXT: [[D2:%.+]] = load double, ptr %d2.addr, align 8644  // CHECK-NEXT: call double @llvm.atan2.f64(double [[D1]], double [[D2]])645  d3 = __builtin_elementwise_atan2(d1, d2);646 647  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16648  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16649  // CHECK-NEXT: call <4 x float> @llvm.atan2.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])650  vf3 = __builtin_elementwise_atan2(vf1, vf2);651}652 653void test_builtin_elementwise_cos(float f1, float f2, double d1, double d2,654                                  float4 vf1, float4 vf2) {655  // CHECK-LABEL: define void @test_builtin_elementwise_cos(656  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4657  // CHECK-NEXT:  call float @llvm.cos.f32(float [[F1]])658  f2 = __builtin_elementwise_cos(f1);659 660  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8661  // CHECK-NEXT: call double @llvm.cos.f64(double [[D1]])662  d2 = __builtin_elementwise_cos(d1);663 664  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16665  // CHECK-NEXT: call <4 x float> @llvm.cos.v4f32(<4 x float> [[VF1]])666  vf2 = __builtin_elementwise_cos(vf1);667}668 669void test_builtin_elementwise_cosh(float f1, float f2, double d1, double d2,670                                  float4 vf1, float4 vf2) {671  // CHECK-LABEL: define void @test_builtin_elementwise_cosh(672  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4673  // CHECK-NEXT:  call float @llvm.cosh.f32(float [[F1]])674  f2 = __builtin_elementwise_cosh(f1);675 676  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8677  // CHECK-NEXT: call double @llvm.cosh.f64(double [[D1]])678  d2 = __builtin_elementwise_cosh(d1);679 680  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16681  // CHECK-NEXT: call <4 x float> @llvm.cosh.v4f32(<4 x float> [[VF1]])682  vf2 = __builtin_elementwise_cosh(vf1);683}684 685void test_builtin_elementwise_exp(float f1, float f2, double d1, double d2,686                                  float4 vf1, float4 vf2) {687  // CHECK-LABEL: define void @test_builtin_elementwise_exp(688  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4689  // CHECK-NEXT:  call float @llvm.exp.f32(float [[F1]])690  f2 = __builtin_elementwise_exp(f1);691 692  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8693  // CHECK-NEXT: call double @llvm.exp.f64(double [[D1]])694  d2 = __builtin_elementwise_exp(d1);695 696  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16697  // CHECK-NEXT: call <4 x float> @llvm.exp.v4f32(<4 x float> [[VF1]])698  vf2 = __builtin_elementwise_exp(vf1);699}700 701void test_builtin_elementwise_exp2(float f1, float f2, double d1, double d2,702                                  float4 vf1, float4 vf2) {703  // CHECK-LABEL: define void @test_builtin_elementwise_exp2(704  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4705  // CHECK-NEXT:  call float @llvm.exp2.f32(float [[F1]])706  f2 = __builtin_elementwise_exp2(f1);707 708  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8709  // CHECK-NEXT: call double @llvm.exp2.f64(double [[D1]])710  d2 = __builtin_elementwise_exp2(d1);711 712  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16713  // CHECK-NEXT: call <4 x float> @llvm.exp2.v4f32(<4 x float> [[VF1]])714  vf2 = __builtin_elementwise_exp2(vf1);715}716 717void test_builtin_elementwise_exp10(float f1, float f2, double d1, double d2,718                                  float4 vf1, float4 vf2) {719  // CHECK-LABEL: define void @test_builtin_elementwise_exp10(720  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4721  // CHECK-NEXT:  call float @llvm.exp10.f32(float [[F1]])722  f2 = __builtin_elementwise_exp10(f1);723 724  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8725  // CHECK-NEXT: call double @llvm.exp10.f64(double [[D1]])726  d2 = __builtin_elementwise_exp10(d1);727 728  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16729  // CHECK-NEXT: call <4 x float> @llvm.exp10.v4f32(<4 x float> [[VF1]])730  vf2 = __builtin_elementwise_exp10(vf1);731}732 733void test_builtin_elementwise_ldexp(float f1, float f2, double d1, double d2,734                                    float4 vf1, float4 vf2, int i1, int4 vi1, short s1, long l1) {735  // CHECK-LABEL: define void @test_builtin_elementwise_ldexp(736  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4737  // CHECK:      [[I1:%.+]] = load i32, ptr %i1.addr, align 4738  // CHECK-NEXT: call float @llvm.ldexp.f32.i32(float [[F1]], i32 [[I1]])739  f2 = __builtin_elementwise_ldexp(f1, i1);740 741  // CHECK:      [[F2:%.+]] = load float, ptr %f1.addr, align 4742  // CHECK:      [[S1:%.+]] = load i16, ptr %s1.addr, align 2743  // CHECK:      [[Ext1:%.+]] = sext i16 [[S1]] to i32744  // CHECK-NEXT: call float @llvm.ldexp.f32.i32(float [[F2]], i32 [[Ext1]])745  f2 = __builtin_elementwise_ldexp(f1, s1);746 747  // CHECK:      [[F3:%.+]] = load float, ptr %f1.addr, align 4748  // CHECK:      [[L1:%.+]] = load i64, ptr %l1.addr, align 8749  // CHECK-NEXT: call float @llvm.ldexp.f32.i64(float [[F3]], i64 [[L1]])750  f2 = __builtin_elementwise_ldexp(f1, l1);751 752  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8753  // CHECK:      [[I2:%.+]] = load i32, ptr %i1.addr, align 4754  // CHECK-NEXT: call double @llvm.ldexp.f64.i32(double [[D1]], i32 [[I2]])755  d2 = __builtin_elementwise_ldexp(d1, i1);756 757  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16758  // CHECK:      [[VI1:%.+]] = load <4 x i32>, ptr %vi1.addr, align 16759  // CHECK-NEXT: call <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float> [[VF1]], <4 x i32> [[VI1]])760  vf2 = __builtin_elementwise_ldexp(vf1, vi1);761}762 763void test_builtin_elementwise_floor(float f1, float f2, double d1, double d2,764                                    float4 vf1, float4 vf2) {765  // CHECK-LABEL: define void @test_builtin_elementwise_floor(766  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4767  // CHECK-NEXT:  call float @llvm.floor.f32(float [[F1]])768  f2 = __builtin_elementwise_floor(f1);769 770  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8771  // CHECK-NEXT: call double @llvm.floor.f64(double [[D1]])772  d2 = __builtin_elementwise_floor(d1);773 774  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16775  // CHECK-NEXT: call <4 x float> @llvm.floor.v4f32(<4 x float> [[VF1]])776  vf2 = __builtin_elementwise_floor(vf1);777}778 779void test_builtin_elementwise_log(float f1, float f2, double d1, double d2,780                                  float4 vf1, float4 vf2) {781  // CHECK-LABEL: define void @test_builtin_elementwise_log(782  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4783  // CHECK-NEXT:  call float @llvm.log.f32(float [[F1]])784  f2 = __builtin_elementwise_log(f1);785 786  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8787  // CHECK-NEXT: call double @llvm.log.f64(double [[D1]])788  d2 = __builtin_elementwise_log(d1);789 790  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16791  // CHECK-NEXT: call <4 x float> @llvm.log.v4f32(<4 x float> [[VF1]])792  vf2 = __builtin_elementwise_log(vf1);793}794 795void test_builtin_elementwise_log10(float f1, float f2, double d1, double d2,796                                  float4 vf1, float4 vf2) {797  // CHECK-LABEL: define void @test_builtin_elementwise_log10(798  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4799  // CHECK-NEXT:  call float @llvm.log10.f32(float [[F1]])800  f2 = __builtin_elementwise_log10(f1);801 802  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8803  // CHECK-NEXT: call double @llvm.log10.f64(double [[D1]])804  d2 = __builtin_elementwise_log10(d1);805 806  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16807  // CHECK-NEXT: call <4 x float> @llvm.log10.v4f32(<4 x float> [[VF1]])808  vf2 = __builtin_elementwise_log10(vf1);809}810 811void test_builtin_elementwise_log2(float f1, float f2, double d1, double d2,812                                  float4 vf1, float4 vf2) {813  // CHECK-LABEL: define void @test_builtin_elementwise_log2(814  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4815  // CHECK-NEXT:  call float @llvm.log2.f32(float [[F1]])816  f2 = __builtin_elementwise_log2(f1);817 818  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8819  // CHECK-NEXT: call double @llvm.log2.f64(double [[D1]])820  d2 = __builtin_elementwise_log2(d1);821 822  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16823  // CHECK-NEXT: call <4 x float> @llvm.log2.v4f32(<4 x float> [[VF1]])824  vf2 = __builtin_elementwise_log2(vf1);825}826 827void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1,828                                       long long int i2, short si,829                                       _BitInt(31) bi1, _BitInt(31) bi2,830                                       char ci) {831  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr, align 8832  // CHECK-NEXT: call i64 @llvm.ctpop.i64(i64 [[I1]])833  i2 = __builtin_elementwise_popcount(i1);834 835  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16836  // CHECK-NEXT: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> [[VI1]])837  vi2 = __builtin_elementwise_popcount(vi1);838 839  // CHECK:      [[CVI2:%.+]] = load <8 x i16>, ptr %cvi2, align 16840  // CHECK-NEXT: call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> [[CVI2]])841  const si8 cvi2 = vi2;842  vi2 = __builtin_elementwise_popcount(cvi2);843 844  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi1.addr, align 4845  // CHECK-NEXT: [[LOADEDV:%.+]] = trunc i32 [[BI1]] to i31846  // CHECK-NEXT: call i31 @llvm.ctpop.i31(i31 [[LOADEDV]])847  bi2 = __builtin_elementwise_popcount(bi1);848 849  // CHECK:      [[IA1:%.+]] = load i32, ptr addrspace(1) @int_as_one, align 4850  // CHECK-NEXT: call i32 @llvm.ctpop.i32(i32 [[IA1]])851  b = __builtin_elementwise_popcount(int_as_one);852 853  // CHECK:      store i32 30, ptr @b, align 4854  b = __builtin_elementwise_popcount(-10);855 856  // CHECK:      [[SI:%.+]] = load i16, ptr %si.addr, align 2857  // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.ctpop.i16(i16 [[SI]])858  si = __builtin_elementwise_popcount(si);859 860  // CHECK:      store i16 3, ptr %si.addr, align 2861  si = __builtin_elementwise_popcount((unsigned short)32771);862 863  // CHECK:      store i16 3, ptr %si.addr, align 2864  si = __builtin_elementwise_popcount((short)32771);865 866  // CHECK:      [[CI:%.+]] = load i8, ptr %ci.addr, align 1867  // CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.ctpop.i8(i8 [[CI]])868  ci = __builtin_elementwise_popcount(ci);869 870  // CHECK:      store i8 2, ptr %ci.addr, align 1871  ci = __builtin_elementwise_popcount((unsigned char)192);872 873  // CHECK:      store i8 2, ptr %ci.addr, align 1874  ci = __builtin_elementwise_popcount((char)192);875}876 877void test_builtin_elementwise_fmod(float f1, float f2, double d1, double d2,878                                      float4 vf1, float4 vf2) {879 880  // CHECK-LABEL: define void @test_builtin_elementwise_fmod(881  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4882  // CHECK:      [[F2:%.+]] = load float, ptr %f2.addr, align 4883  // CHECK-NEXT:  frem float [[F1]], [[F2]]884  f2 = __builtin_elementwise_fmod(f1, f2);885 886  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8887  // CHECK:      [[D2:%.+]] = load double, ptr %d2.addr, align 8888  // CHECK-NEXT: frem double [[D1]], [[D2]]889  d2 = __builtin_elementwise_fmod(d1, d2);890 891  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16892  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16893  // CHECK-NEXT: frem <4 x float> [[VF1]], [[VF2]]894  vf2 = __builtin_elementwise_fmod(vf1, vf2);895}896 897void test_builtin_elementwise_pow(float f1, float f2, double d1, double d2,898                                      float4 vf1, float4 vf2) {899 900  // CHECK-LABEL: define void @test_builtin_elementwise_pow(901  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4902  // CHECK:      [[F2:%.+]] = load float, ptr %f2.addr, align 4903  // CHECK-NEXT:  call float @llvm.pow.f32(float [[F1]], float [[F2]])904  f2 = __builtin_elementwise_pow(f1, f2);905 906  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8907  // CHECK:      [[D2:%.+]] = load double, ptr %d2.addr, align 8908  // CHECK-NEXT: call double @llvm.pow.f64(double [[D1]], double [[D2]])909  d2 = __builtin_elementwise_pow(d1, d2);910 911  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16912  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16913  // CHECK-NEXT: call <4 x float> @llvm.pow.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])914  vf2 = __builtin_elementwise_pow(vf1, vf2);915}916 917void test_builtin_elementwise_roundeven(float f1, float f2, double d1, double d2,918                                        float4 vf1, float4 vf2) {919  // CHECK-LABEL: define void @test_builtin_elementwise_roundeven(920  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4921  // CHECK-NEXT:  call float @llvm.roundeven.f32(float [[F1]])922  f2 = __builtin_elementwise_roundeven(f1);923 924  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8925  // CHECK-NEXT: call double @llvm.roundeven.f64(double [[D1]])926  d2 = __builtin_elementwise_roundeven(d1);927 928  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16929  // CHECK-NEXT: call <4 x float> @llvm.roundeven.v4f32(<4 x float> [[VF1]])930  vf2 = __builtin_elementwise_roundeven(vf1);931}932 933void test_builtin_elementwise_round(float f1, float f2, double d1, double d2,934                                        float4 vf1, float4 vf2) {935  // CHECK-LABEL: define void @test_builtin_elementwise_round(936  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4937  // CHECK-NEXT:  call float @llvm.round.f32(float [[F1]])938  f2 = __builtin_elementwise_round(f1);939 940  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8941  // CHECK-NEXT: call double @llvm.round.f64(double [[D1]])942  d2 = __builtin_elementwise_round(d1);943 944  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16945  // CHECK-NEXT: call <4 x float> @llvm.round.v4f32(<4 x float> [[VF1]])946  vf2 = __builtin_elementwise_round(vf1);947}948 949void test_builtin_elementwise_rint(float f1, float f2, double d1, double d2,950                                   float4 vf1, float4 vf2) {951  // CHECK-LABEL: define void @test_builtin_elementwise_rint(952  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4953  // CHECK-NEXT:  call float @llvm.rint.f32(float [[F1]])954  f2 = __builtin_elementwise_rint(f1);955 956  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8957  // CHECK-NEXT: call double @llvm.rint.f64(double [[D1]])958  d2 = __builtin_elementwise_rint(d1);959 960  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16961  // CHECK-NEXT: call <4 x float> @llvm.rint.v4f32(<4 x float> [[VF1]])962  vf2 = __builtin_elementwise_rint(vf1);963}964 965void test_builtin_elementwise_nearbyint(float f1, float f2, double d1, double d2,966                                        float4 vf1, float4 vf2) {967  // CHECK-LABEL: define void @test_builtin_elementwise_nearbyint(968  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4969  // CHECK-NEXT:  call float @llvm.nearbyint.f32(float [[F1]])970  f2 = __builtin_elementwise_nearbyint(f1);971 972  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8973  // CHECK-NEXT: call double @llvm.nearbyint.f64(double [[D1]])974  d2 = __builtin_elementwise_nearbyint(d1);975 976  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16977  // CHECK-NEXT: call <4 x float> @llvm.nearbyint.v4f32(<4 x float> [[VF1]])978  vf2 = __builtin_elementwise_nearbyint(vf1);979}980 981void test_builtin_elementwise_sin(float f1, float f2, double d1, double d2,982                                  float4 vf1, float4 vf2) {983  // CHECK-LABEL: define void @test_builtin_elementwise_sin(984  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4985  // CHECK-NEXT:  call float @llvm.sin.f32(float [[F1]])986  f2 = __builtin_elementwise_sin(f1);987 988  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8989  // CHECK-NEXT: call double @llvm.sin.f64(double [[D1]])990  d2 = __builtin_elementwise_sin(d1);991 992  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16993  // CHECK-NEXT: call <4 x float> @llvm.sin.v4f32(<4 x float> [[VF1]])994  vf2 = __builtin_elementwise_sin(vf1);995}996 997void test_builtin_elementwise_sinh(float f1, float f2, double d1, double d2,998                                  float4 vf1, float4 vf2) {999  // CHECK-LABEL: define void @test_builtin_elementwise_sinh(1000  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41001  // CHECK-NEXT:  call float @llvm.sinh.f32(float [[F1]])1002  f2 = __builtin_elementwise_sinh(f1);1003 1004  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81005  // CHECK-NEXT: call double @llvm.sinh.f64(double [[D1]])1006  d2 = __builtin_elementwise_sinh(d1);1007 1008  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161009  // CHECK-NEXT: call <4 x float> @llvm.sinh.v4f32(<4 x float> [[VF1]])1010  vf2 = __builtin_elementwise_sinh(vf1);1011}1012 1013void test_builtin_elementwise_sqrt(float f1, float f2, double d1, double d2,1014                                  float4 vf1, float4 vf2) {1015  // CHECK-LABEL: define void @test_builtin_elementwise_sqrt(1016  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41017  // CHECK-NEXT:  call float @llvm.sqrt.f32(float [[F1]])1018  f2 = __builtin_elementwise_sqrt(f1);1019 1020  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81021  // CHECK-NEXT: call double @llvm.sqrt.f64(double [[D1]])1022  d2 = __builtin_elementwise_sqrt(d1);1023 1024  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161025  // CHECK-NEXT: call <4 x float> @llvm.sqrt.v4f32(<4 x float> [[VF1]])1026  vf2 = __builtin_elementwise_sqrt(vf1);1027}1028 1029void test_builtin_elementwise_tan(float f1, float f2, double d1, double d2,1030                                  float4 vf1, float4 vf2) {1031  // CHECK-LABEL: define void @test_builtin_elementwise_tan(1032  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41033  // CHECK-NEXT:  call float @llvm.tan.f32(float [[F1]])1034  f2 = __builtin_elementwise_tan(f1);1035 1036  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81037  // CHECK-NEXT: call double @llvm.tan.f64(double [[D1]])1038  d2 = __builtin_elementwise_tan(d1);1039 1040  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161041  // CHECK-NEXT: call <4 x float> @llvm.tan.v4f32(<4 x float> [[VF1]])1042  vf2 = __builtin_elementwise_tan(vf1);1043}1044 1045void test_builtin_elementwise_tanh(float f1, float f2, double d1, double d2,1046                                  float4 vf1, float4 vf2) {1047  // CHECK-LABEL: define void @test_builtin_elementwise_tanh(1048  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41049  // CHECK-NEXT:  call float @llvm.tanh.f32(float [[F1]])1050  f2 = __builtin_elementwise_tanh(f1);1051 1052  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81053  // CHECK-NEXT: call double @llvm.tanh.f64(double [[D1]])1054  d2 = __builtin_elementwise_tanh(d1);1055 1056  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161057  // CHECK-NEXT: call <4 x float> @llvm.tanh.v4f32(<4 x float> [[VF1]])1058  vf2 = __builtin_elementwise_tanh(vf1);1059}1060 1061void test_builtin_elementwise_trunc(float f1, float f2, double d1, double d2,1062                                    float4 vf1, float4 vf2) {1063  // CHECK-LABEL: define void @test_builtin_elementwise_trunc(1064  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41065  // CHECK-NEXT:  call float @llvm.trunc.f32(float [[F1]])1066  f2 = __builtin_elementwise_trunc(f1);1067 1068  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81069  // CHECK-NEXT: call double @llvm.trunc.f64(double [[D1]])1070  d2 = __builtin_elementwise_trunc(d1);1071 1072  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161073  // CHECK-NEXT: call <4 x float> @llvm.trunc.v4f32(<4 x float> [[VF1]])1074  vf2 = __builtin_elementwise_trunc(vf1);1075}1076 1077void test_builtin_elementwise_canonicalize(float f1, float f2, double d1, double d2,1078                                           float4 vf1, float4 vf2) {1079  // CHECK-LABEL: define void @test_builtin_elementwise_canonicalize(1080  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41081  // CHECK-NEXT:  call float @llvm.canonicalize.f32(float [[F1]])1082  f2 = __builtin_elementwise_canonicalize(f1);1083 1084  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81085  // CHECK-NEXT: call double @llvm.canonicalize.f64(double [[D1]])1086  d2 = __builtin_elementwise_canonicalize(d1);1087 1088  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161089  // CHECK-NEXT: call <4 x float> @llvm.canonicalize.v4f32(<4 x float> [[VF1]])1090  vf2 = __builtin_elementwise_canonicalize(vf1);1091}1092 1093void test_builtin_elementwise_copysign(float f1, float f2, double d1, double d2,1094                                       float4 vf1, float4 vf2, double2 v2f64) {1095  // CHECK-LABEL: define void @test_builtin_elementwise_copysign(1096  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 41097  // CHECK-NEXT: [[F2:%.+]] = load float, ptr %f2.addr, align 41098  // CHECK-NEXT:  call float @llvm.copysign.f32(float %0, float %1)1099  f1 = __builtin_elementwise_copysign(f1, f2);1100 1101  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81102  // CHECK-NEXT: [[D2:%.+]] = load double, ptr %d2.addr, align 81103  // CHECK-NEXT: call double @llvm.copysign.f64(double [[D1]], double [[D2]])1104  d1 = __builtin_elementwise_copysign(d1, d2);1105 1106  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 81107  // CHECK-NEXT: call double @llvm.copysign.f64(double [[D1]], double 2.000000e+00)1108  d1 = __builtin_elementwise_copysign(d1, 2.0);1109 1110  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 161111  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 161112  // CHECK-NEXT: call <4 x float> @llvm.copysign.v4f32(<4 x float> [[VF1]], <4 x float> [[VF2]])1113  vf1 = __builtin_elementwise_copysign(vf1, vf2);1114 1115  // CHECK:      [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 161116  // CHECK-NEXT: [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 161117  // CHECK-NEXT: call <4 x float> @llvm.copysign.v4f32(<4 x float> [[CVF1]], <4 x float> [[VF2]])1118  const float4 cvf1 = vf1;1119  vf1 = __builtin_elementwise_copysign(cvf1, vf2);1120 1121  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 161122  // CHECK-NEXT: [[CVF1:%.+]] = load <4 x float>, ptr %cvf1, align 161123  // CHECK-NEXT: call <4 x float> @llvm.copysign.v4f32(<4 x float> [[VF2]], <4 x float> [[CVF1]])1124  vf1 = __builtin_elementwise_copysign(vf2, cvf1);1125 1126 1127  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr1128  // CHECK-NEXT: call float @llvm.copysign.f32(float [[F1]], float 2.000000e+00)1129  f1 = __builtin_elementwise_copysign(f1, 2.0f);1130 1131  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr1132  // CHECK-NEXT: call float @llvm.copysign.f32(float 2.000000e+00, float [[F1]])1133  f1 = __builtin_elementwise_copysign(2.0f, f1);1134 1135  // CHECK:      [[V2F64:%.+]] = load <2 x double>, ptr %v2f64.addr, align 161136  // CHECK-NEXT: call <2 x double> @llvm.copysign.v2f64(<2 x double> splat (double 1.000000e+00), <2 x double> [[V2F64]])1137  v2f64 = __builtin_elementwise_copysign((double2)1.0, v2f64);1138}1139 1140void test_builtin_elementwise_fma(float f32, double f64,1141                                  float2 v2f32, float4 v4f32,1142                                  double2 v2f64, double3 v3f64,1143                                  const float4 c_v4f32,1144                                  half f16, half2 v2f16) {1145  // CHECK-LABEL: define void @test_builtin_elementwise_fma(1146  // CHECK:      [[F32_0:%.+]] = load float, ptr %f32.addr1147  // CHECK-NEXT: [[F32_1:%.+]] = load float, ptr %f32.addr1148  // CHECK-NEXT: [[F32_2:%.+]] = load float, ptr %f32.addr1149  // CHECK-NEXT: call float @llvm.fma.f32(float [[F32_0]], float [[F32_1]], float [[F32_2]])1150  float f2 = __builtin_elementwise_fma(f32, f32, f32);1151 1152  // CHECK:      [[F64_0:%.+]] = load double, ptr %f64.addr1153  // CHECK-NEXT: [[F64_1:%.+]] = load double, ptr %f64.addr1154  // CHECK-NEXT: [[F64_2:%.+]] = load double, ptr %f64.addr1155  // CHECK-NEXT: call double @llvm.fma.f64(double [[F64_0]], double [[F64_1]], double [[F64_2]])1156  double d2 = __builtin_elementwise_fma(f64, f64, f64);1157 1158  // CHECK:      [[V4F32_0:%.+]] = load <4 x float>, ptr %v4f32.addr1159  // CHECK-NEXT: [[V4F32_1:%.+]] = load <4 x float>, ptr %v4f32.addr1160  // CHECK-NEXT: [[V4F32_2:%.+]] = load <4 x float>, ptr %v4f32.addr1161  // CHECK-NEXT: call <4 x float> @llvm.fma.v4f32(<4 x float> [[V4F32_0]], <4 x float> [[V4F32_1]], <4 x float> [[V4F32_2]])1162  float4 tmp_v4f32 = __builtin_elementwise_fma(v4f32, v4f32, v4f32);1163 1164 1165  // FIXME: Are we really still doing the 3 vector load workaround1166  // CHECK:      [[V3F64_LOAD_0:%.+]] = load <4 x double>, ptr %v3f64.addr1167  // CHECK-NEXT: [[V3F64_0:%.+]] = shufflevector1168  // CHECK-NEXT: [[V3F64_LOAD_1:%.+]] = load <4 x double>, ptr %v3f64.addr1169  // CHECK-NEXT: [[V3F64_1:%.+]] = shufflevector1170  // CHECK-NEXT: [[V3F64_LOAD_2:%.+]] = load <4 x double>, ptr %v3f64.addr1171  // CHECK-NEXT: [[V3F64_2:%.+]] = shufflevector1172    // CHECK-NEXT: call <3 x double> @llvm.fma.v3f64(<3 x double> [[V3F64_0]], <3 x double> [[V3F64_1]], <3 x double> [[V3F64_2]])1173  v3f64 = __builtin_elementwise_fma(v3f64, v3f64, v3f64);1174 1175  // CHECK:      [[F64_0:%.+]] = load double, ptr %f64.addr1176  // CHECK-NEXT: [[F64_1:%.+]] = load double, ptr %f64.addr1177  // CHECK-NEXT: [[F64_2:%.+]] = load double, ptr %f64.addr1178  // CHECK-NEXT: call double @llvm.fma.f64(double [[F64_0]], double [[F64_1]], double [[F64_2]])1179  v2f64 = __builtin_elementwise_fma(f64, f64, f64);1180 1181  // CHECK:      [[V4F32_0:%.+]] = load <4 x float>, ptr %c_v4f32.addr1182  // CHECK-NEXT: [[V4F32_1:%.+]] = load <4 x float>, ptr %c_v4f32.addr1183  // CHECK-NEXT: [[V4F32_2:%.+]] = load <4 x float>, ptr %c_v4f32.addr1184  // CHECK-NEXT: call <4 x float> @llvm.fma.v4f32(<4 x float> [[V4F32_0]], <4 x float> [[V4F32_1]], <4 x float> [[V4F32_2]])1185  v4f32 = __builtin_elementwise_fma(c_v4f32, c_v4f32, c_v4f32);1186 1187  // CHECK:      [[F16_0:%.+]] = load half, ptr %f16.addr1188  // CHECK-NEXT: [[F16_1:%.+]] = load half, ptr %f16.addr1189  // CHECK-NEXT: [[F16_2:%.+]] = load half, ptr %f16.addr1190  // CHECK-NEXT: call half @llvm.fma.f16(half [[F16_0]], half [[F16_1]], half [[F16_2]])1191  half tmp_f16 = __builtin_elementwise_fma(f16, f16, f16);1192 1193  // CHECK:      [[V2F16_0:%.+]] = load <2 x half>, ptr %v2f16.addr1194  // CHECK-NEXT: [[V2F16_1:%.+]] = load <2 x half>, ptr %v2f16.addr1195  // CHECK-NEXT: [[V2F16_2:%.+]] = load <2 x half>, ptr %v2f16.addr1196  // CHECK-NEXT: call <2 x half> @llvm.fma.v2f16(<2 x half> [[V2F16_0]], <2 x half> [[V2F16_1]], <2 x half> [[V2F16_2]])1197  half2 tmp0_v2f16 = __builtin_elementwise_fma(v2f16, v2f16, v2f16);1198 1199  // CHECK:      [[V2F16_0:%.+]] = load <2 x half>, ptr %v2f16.addr1200  // CHECK-NEXT: [[V2F16_1:%.+]] = load <2 x half>, ptr %v2f16.addr1201  // CHECK-NEXT: [[F16_2:%.+]] = load half, ptr %f16.addr1202  // CHECK-NEXT: [[V2F16_2_INSERT:%.+]] = insertelement1203  // CHECK-NEXT: [[V2F16_2:%.+]] = shufflevector <2 x half> [[V2F16_2_INSERT]], <2 x half> poison, <2 x i32> zeroinitializer1204  // CHECK-NEXT: call <2 x half> @llvm.fma.v2f16(<2 x half> [[V2F16_0]], <2 x half> [[V2F16_1]], <2 x half> [[V2F16_2]])1205  half2 tmp1_v2f16 = __builtin_elementwise_fma(v2f16, v2f16, (half2)f16);1206 1207  // CHECK:      [[V2F16_0:%.+]] = load <2 x half>, ptr %v2f16.addr1208  // CHECK-NEXT: [[V2F16_1:%.+]] = load <2 x half>, ptr %v2f16.addr1209  // CHECK-NEXT: call <2 x half> @llvm.fma.v2f16(<2 x half> [[V2F16_0]], <2 x half> [[V2F16_1]], <2 x half> splat (half 0xH4400))1210  half2 tmp2_v2f16 = __builtin_elementwise_fma(v2f16, v2f16, (half2)4.0);1211 1212}1213 1214void test_builtin_elementwise_fshl(long long int i1, long long int i2,1215				   long long int i3, unsigned short us1,1216                                   unsigned short us2, unsigned short us3,1217                                   char c1, char c2, char c3,1218                                   unsigned char uc1, unsigned char uc2,1219                                   unsigned char uc3,  si8 vi1, si8 vi2,1220                                   si8 vi3, u4 vu1, u4 vu2, u4 vu3) {1221  // CHECK:      [[I1:%.+]] = load i64, ptr %i1.addr1222  // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr1223  // CHECK-NEXT: [[I3:%.+]] = load i64, ptr %i3.addr1224  // CHECK-NEXT: [[I4:%.+]] = call i64 @llvm.fshl.i64(i64 [[I1]], i64 [[I2]], i64 [[I3]])1225  // CHECK-NEXT:              store i64 [[I4]], ptr %tmp_lli_l1226  // CHECK-NEXT: [[I5:%.+]] = load i64, ptr %i1.addr1227  // CHECK-NEXT: [[I6:%.+]] = load i64, ptr %i2.addr1228  // CHECK-NEXT: [[I7:%.+]] = load i64, ptr %i3.addr1229  // CHECK-NEXT: [[I8:%.+]] = call i64 @llvm.fshr.i64(i64 [[I5]], i64 [[I6]], i64 [[I7]])1230  // CHECK-NEXT:              store i64 [[I8]], ptr %tmp_lli_r1231  long long int tmp_lli_l = __builtin_elementwise_fshl(i1, i2, i3);1232  long long int tmp_lli_r = __builtin_elementwise_fshr(i1, i2, i3);1233 1234  // CHECK:      [[US1:%.+]] = load i16, ptr %us1.addr1235  // CHECK-NEXT: [[US2:%.+]] = load i16, ptr %us2.addr1236  // CHECK-NEXT: [[US3:%.+]] = load i16, ptr %us3.addr1237  // CHECK-NEXT: [[US4:%.+]] = call i16 @llvm.fshl.i16(i16 [[US1]], i16 [[US2]], i16 [[US3]])1238  // CHECK-NEXT:               store i16 [[US4]], ptr %tmp_usi_l1239  // CHECK-NEXT: [[US5:%.+]] = load i16, ptr %us1.addr1240  // CHECK-NEXT: [[US6:%.+]] = load i16, ptr %us2.addr1241  // CHECK-NEXT: [[US7:%.+]] = load i16, ptr %us3.addr1242  // CHECK-NEXT: [[US8:%.+]] = call i16 @llvm.fshr.i16(i16 [[US5]], i16 [[US6]], i16 [[US7]])1243  // CHECK-NEXT:               store i16 [[US8]], ptr %tmp_usi_r1244  unsigned short tmp_usi_l = __builtin_elementwise_fshl(us1, us2, us3);1245  unsigned short tmp_usi_r = __builtin_elementwise_fshr(us1, us2, us3);1246 1247  // CHECK:      [[C1:%.+]] = load i8, ptr %c1.addr1248  // CHECK-NEXT: [[C2:%.+]] = load i8, ptr %c2.addr1249  // CHECK-NEXT: [[C3:%.+]] = load i8, ptr %c3.addr1250  // CHECK-NEXT: [[C4:%.+]] = call i8 @llvm.fshl.i8(i8 [[C1]], i8 [[C2]], i8 [[C3]])1251  // CHECK-NEXT:              store i8 [[C4]], ptr %tmp_c_l1252  // CHECK-NEXT: [[C5:%.+]] = load i8, ptr %c1.addr1253  // CHECK-NEXT: [[C6:%.+]] = load i8, ptr %c2.addr1254  // CHECK-NEXT: [[C7:%.+]] = load i8, ptr %c3.addr1255  // CHECK-NEXT: [[C8:%.+]] = call i8 @llvm.fshr.i8(i8 [[C5]], i8 [[C6]], i8 [[C7]])1256  // CHECK-NEXT:              store i8 [[C8]], ptr %tmp_c_r1257  char tmp_c_l = __builtin_elementwise_fshl(c1, c2, c3);1258  char tmp_c_r = __builtin_elementwise_fshr(c1, c2, c3);1259 1260  // CHECK:      [[UC1:%.+]] = load i8, ptr %uc1.addr1261  // CHECK-NEXT: [[UC2:%.+]] = load i8, ptr %uc2.addr1262  // CHECK-NEXT: [[UC3:%.+]] = load i8, ptr %uc3.addr1263  // CHECK-NEXT: [[UC4:%.+]] = call i8 @llvm.fshl.i8(i8 [[UC1]], i8 [[UC2]], i8 [[UC3]])1264  // CHECK-NEXT:               store i8 [[UC4]], ptr %tmp_uc_l1265  // CHECK-NEXT: [[UC5:%.+]] = load i8, ptr %uc1.addr1266  // CHECK-NEXT: [[UC6:%.+]] = load i8, ptr %uc2.addr1267  // CHECK-NEXT: [[UC7:%.+]] = load i8, ptr %uc3.addr1268  // CHECK-NEXT: [[UC8:%.+]] = call i8 @llvm.fshr.i8(i8 [[UC5]], i8 [[UC6]], i8 [[UC7]])1269  // CHECK-NEXT:               store i8 [[UC8]], ptr %tmp_uc_r1270  unsigned char tmp_uc_l = __builtin_elementwise_fshl(uc1, uc2, uc3);1271  unsigned char tmp_uc_r = __builtin_elementwise_fshr(uc1, uc2, uc3);1272 1273  // CHECK:      [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr1274  // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr1275  // CHECK-NEXT: [[VI3:%.+]] = load <8 x i16>, ptr %vi3.addr1276  // CHECK-NEXT: [[VI4:%.+]] = call <8 x i16> @llvm.fshl.v8i16(<8 x i16> [[VI1]], <8 x i16> [[VI2]], <8 x i16> [[VI3]])1277  // CHECK-NEXT:               store <8 x i16> [[VI4]], ptr %tmp_vi_l1278  // CHECK-NEXT: [[VI5:%.+]] = load <8 x i16>, ptr %vi1.addr1279  // CHECK-NEXT: [[VI6:%.+]] = load <8 x i16>, ptr %vi2.addr1280  // CHECK-NEXT: [[VI7:%.+]] = load <8 x i16>, ptr %vi3.addr1281  // CHECK-NEXT: [[VI8:%.+]] = call <8 x i16> @llvm.fshr.v8i16(<8 x i16> [[VI5]], <8 x i16> [[VI6]], <8 x i16> [[VI7]])1282  // CHECK-NEXT:               store <8 x i16> [[VI8]], ptr %tmp_vi_r1283  si8 tmp_vi_l = __builtin_elementwise_fshl(vi1, vi2, vi3);1284  si8 tmp_vi_r = __builtin_elementwise_fshr(vi1, vi2, vi3);1285 1286  // CHECK:      [[VU1:%.+]] = load <4 x i32>, ptr %vu1.addr1287  // CHECK-NEXT: [[VU2:%.+]] = load <4 x i32>, ptr %vu2.addr1288  // CHECK-NEXT: [[VU3:%.+]] = load <4 x i32>, ptr %vu3.addr1289  // CHECK-NEXT: [[VU4:%.+]] = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]], <4 x i32> [[VU3]])1290  // CHECK-NEXT:               store <4 x i32> [[VU4]], ptr %tmp_vu_l1291  // CHECK-NEXT: [[VU5:%.+]] = load <4 x i32>, ptr %vu1.addr1292  // CHECK-NEXT: [[VU6:%.+]] = load <4 x i32>, ptr %vu2.addr1293  // CHECK-NEXT: [[VU7:%.+]] = load <4 x i32>, ptr %vu3.addr1294  // CHECK-NEXT: [[VU8:%.+]] = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> [[VU5]], <4 x i32> [[VU6]], <4 x i32> [[VU7]])1295  // CHECK-NEXT:               store <4 x i32> [[VU8]], ptr %tmp_vu_r1296  u4 tmp_vu_l = __builtin_elementwise_fshl(vu1, vu2, vu3);1297  u4 tmp_vu_r = __builtin_elementwise_fshr(vu1, vu2, vu3);1298}1299 1300void test_builtin_elementwise_clzg(si8 vs1, si8 vs2, u4 vu1,1301                                   long long int lli, short si,1302                                   _BitInt(31) bi, int i,1303                                   char ci) {1304  // CHECK:      [[V8S1:%.+]] = load <8 x i16>, ptr %vs1.addr1305  // CHECK-NEXT: call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> [[V8S1]], i1 true)1306  vs1 = __builtin_elementwise_clzg(vs1);1307 1308  // CHECK:      [[V8S1:%.+]] = load <8 x i16>, ptr %vs1.addr1309  // CHECK-NEXT: [[CLZ:%.+]] = call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> [[V8S1]], i1 true)1310  // CHECK-NEXT: [[ISZERO:%.+]] = icmp eq <8 x i16> [[V8S1]], zeroinitializer1311  // CHECK-NEXT: [[V8S2:%.+]] = load <8 x i16>, ptr %vs2.addr1312  // select <8 x i1> [[ISZERO]], <8 x i16> [[CLZ]], <8 x i16> [[V8S2]]1313  vs1 = __builtin_elementwise_clzg(vs1, vs2);1314 1315  // CHECK:      [[V4U1:%.+]] = load <4 x i32>, ptr %vu1.addr1316  // CHECK-NEXT: call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> [[V4U1]], i1 true)1317  vu1 = __builtin_elementwise_clzg(vu1);1318 1319  // CHECK:      [[LLI:%.+]] = load i64, ptr %lli.addr1320  // CHECK-NEXT: call i64 @llvm.ctlz.i64(i64 [[LLI]], i1 true)1321  lli = __builtin_elementwise_clzg(lli);1322 1323  // CHECK:      [[SI:%.+]] = load i16, ptr %si.addr1324  // CHECK-NEXT: call i16 @llvm.ctlz.i16(i16 [[SI]], i1 true)1325  si = __builtin_elementwise_clzg(si);1326 1327  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi.addr1328  // CHECK-NEXT: [[BI2:%.+]] = trunc i32 [[BI1]] to i311329  // CHECK-NEXT: call i31 @llvm.ctlz.i31(i31 [[BI2]], i1 true)1330  bi = __builtin_elementwise_clzg(bi);1331 1332  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi.addr1333  // CHECK-NEXT: [[BI2:%.+]] = trunc i32 [[BI1]] to i311334  // CHECK-NEXT: [[CLZ:%.+]] = call i31 @llvm.ctlz.i31(i31 [[BI2]], i1 true)1335  // CHECK-NEXT: [[ISZERO:%.+]] = icmp eq i31 [[BI2]], 01336  // CHECK-NEXT: select i1 [[ISZERO]], i31 1, i31 [[CLZ]]1337  bi = __builtin_elementwise_clzg(bi, (_BitInt(31))1);1338 1339  // CHECK:      [[I:%.+]] = load i32, ptr %i.addr1340  // CHECK-NEXT: call i32 @llvm.ctlz.i32(i32 [[I]], i1 true)1341  i = __builtin_elementwise_clzg(i);1342 1343  // CHECK:      [[CI:%.+]] = load i8, ptr %ci.addr1344  // CHECK-NEXT: call i8 @llvm.ctlz.i8(i8 [[CI]], i1 true)1345  ci = __builtin_elementwise_clzg(ci);1346}1347 1348void test_builtin_elementwise_ctzg(si8 vs1, si8 vs2, u4 vu1,1349                                   long long int lli, short si,1350                                   _BitInt(31) bi, int i,1351                                   char ci) {1352  // CHECK:      [[V8S1:%.+]] = load <8 x i16>, ptr %vs1.addr1353  // CHECK-NEXT: call <8 x i16> @llvm.cttz.v8i16(<8 x i16> [[V8S1]], i1 true)1354  vs1 = __builtin_elementwise_ctzg(vs1);1355 1356  // CHECK:      [[V8S1:%.+]] = load <8 x i16>, ptr %vs1.addr1357  // CHECK-NEXT: [[ctz:%.+]] = call <8 x i16> @llvm.cttz.v8i16(<8 x i16> [[V8S1]], i1 true)1358  // CHECK-NEXT: [[ISZERO:%.+]] = icmp eq <8 x i16> [[V8S1]], zeroinitializer1359  // CHECK-NEXT: [[V8S2:%.+]] = load <8 x i16>, ptr %vs2.addr1360  // select <8 x i1> [[ISZERO]], <8 x i16> [[ctz]], <8 x i16> [[V8S2]]1361  vs1 = __builtin_elementwise_ctzg(vs1, vs2);1362 1363  // CHECK:      [[V4U1:%.+]] = load <4 x i32>, ptr %vu1.addr1364  // CHECK-NEXT: call <4 x i32> @llvm.cttz.v4i32(<4 x i32> [[V4U1]], i1 true)1365  vu1 = __builtin_elementwise_ctzg(vu1);1366 1367  // CHECK:      [[LLI:%.+]] = load i64, ptr %lli.addr1368  // CHECK-NEXT: call i64 @llvm.cttz.i64(i64 [[LLI]], i1 true)1369  lli = __builtin_elementwise_ctzg(lli);1370 1371  // CHECK:      [[SI:%.+]] = load i16, ptr %si.addr1372  // CHECK-NEXT: call i16 @llvm.cttz.i16(i16 [[SI]], i1 true)1373  si = __builtin_elementwise_ctzg(si);1374 1375  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi.addr1376  // CHECK-NEXT: [[BI2:%.+]] = trunc i32 [[BI1]] to i311377  // CHECK-NEXT: call i31 @llvm.cttz.i31(i31 [[BI2]], i1 true)1378  bi = __builtin_elementwise_ctzg(bi);1379 1380  // CHECK:      [[BI1:%.+]] = load i32, ptr %bi.addr1381  // CHECK-NEXT: [[BI2:%.+]] = trunc i32 [[BI1]] to i311382  // CHECK-NEXT: [[ctz:%.+]] = call i31 @llvm.cttz.i31(i31 [[BI2]], i1 true)1383  // CHECK-NEXT: [[ISZERO:%.+]] = icmp eq i31 [[BI2]], 01384  // CHECK-NEXT: select i1 [[ISZERO]], i31 1, i31 [[ctz]]1385  bi = __builtin_elementwise_ctzg(bi, (_BitInt(31))1);1386 1387  // CHECK:      [[I:%.+]] = load i32, ptr %i.addr1388  // CHECK-NEXT: call i32 @llvm.cttz.i32(i32 [[I]], i1 true)1389  i = __builtin_elementwise_ctzg(i);1390 1391  // CHECK:      [[CI:%.+]] = load i8, ptr %ci.addr1392  // CHECK-NEXT: call i8 @llvm.cttz.i8(i8 [[CI]], i1 true)1393  ci = __builtin_elementwise_ctzg(ci);1394}1395