amyk created this revision.
amyk added reviewers: PowerPC, nemanjai, stefanp, power-llvm-team, bmahjour.
amyk added projects: LLVM, PowerPC, clang.
Herald added a subscriber: shchenz.
amyk requested review of this revision.

This patch implements the initialization of vectors under the 
`-faltivec-src-compat=xl` option
introduced in https://reviews.llvm.org/D103615.

Under this option, the initialization of scalar vectors, `vector bool`, and 
`vector pixel` are
treated the same, where the initialization value is splatted across the whole 
vector.

This patch does not change the behaviour of the `-faltivec-src-compat=mixed` 
option, 
which is the current default for Clang.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106120

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/vector-bool-pixel-altivec-init.c
  clang/test/CodeGen/vector-bool-pixel-altivec-init2.c
  clang/test/CodeGen/vector-scalar-altivec-init.c
  clang/test/CodeGen/vector-scalar-altivec-init2.c

Index: clang/test/CodeGen/vector-scalar-altivec-init2.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/vector-scalar-altivec-init2.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+
+vector char vi8_1;
+vector char vi8_2;
+vector unsigned char vui8_1;
+vector unsigned char vui8_2;
+
+vector short vi16_1;
+vector short vi16_2;
+vector unsigned short vui16_1;
+vector unsigned short vui16_2;
+
+vector int vi32_1;
+vector int vi32_2;
+vector unsigned int vui32_1;
+vector unsigned int vui32_2;
+
+vector long long vi64_1;
+vector long long vi64_2;
+vector unsigned long long vui64_1;
+vector unsigned long long vui64_2;
+
+vector float f1;
+vector float f2;
+vector double d1;
+vector double d2;
+
+////////////////////////////////////////////////////////////////////////////////
+void test_vector_scalar_init() {
+  // vector char initialization
+  vi8_1 = (vector char)'A';
+  // CHECK: <i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65>
+  char two = '2';
+  vi8_2 = (vector char)two;
+  // CHECK: %splat.splatinsert = insertelement <16 x i8>
+  // CHECK: %splat.splat = shufflevector <16 x i8>
+
+  vui8_1 = (vector unsigned char)'B';
+  // CHECK: <i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66>
+  unsigned char three = '3';
+  vui8_2 = (vector unsigned char)three;
+  // CHECK: %splat.splatinsert1 = insertelement <16 x i8>
+  // CHECK: %splat.splat2 = shufflevector <16 x i8>
+
+  // vector short initialization
+  vi16_1 = (vector short)5;
+  // CHECK: <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+  short six = 6;
+  vi16_2 = (vector short)six;
+  // CHECK: %splat.splatinsert3 = insertelement <8 x i16>
+  // CHECK: %splat.splat4 = shufflevector <8 x i16>
+
+  vui16_1 = (vector unsigned short)7;
+  // CHECK: <i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7>
+  unsigned short eight = 8;
+  vui16_2 = (vector unsigned short)eight;
+  // CHECK: %splat.splatinsert5 = insertelement <8 x i16>
+  // CHECK: %splat.splat6 = shufflevector <8 x i16>
+
+  // vector int initialization
+  vi32_1 = (vector int)9;
+  // CHECK: <i32 9, i32 9, i32 9, i32 9>
+  int ten = 10;
+  vi32_2 = (vector int)ten;
+  // CHECK: %splat.splatinsert7 = insertelement <4 x i32>
+  // CHECK: %splat.splat8 = shufflevector <4 x i32>
+
+  vui32_1 = (vector unsigned int)11;
+  // CHECK: <i32 11, i32 11, i32 11, i32 11>
+  unsigned int twelve = 12;
+  vui32_2 = (vector unsigned int)twelve;
+  // CHECK: %splat.splatinsert9 = insertelement <4 x i32>
+  // CHECK: %splat.splat10 = shufflevector <4 x i32>
+
+  // vector long long initialization
+  vi64_1 = (vector long long)143;
+  // CHECK: <i64 143, i64 143>
+  long long thousand = 1000;
+  vi64_1 = (vector long long)thousand;
+  // CHECK: %splat.splatinsert11 = insertelement <2 x i64>
+  // CHECK: %splat.splat12 = shufflevector <2 x i64>
+
+  vui64_1 = (vector unsigned long long)99;
+  // CHECK: <i64 99, i64 99>
+  unsigned long long twothousand = 2000;
+  vui64_1 = (vector unsigned long long)twothousand;
+  // CHECK: %splat.splatinsert13 = insertelement <2 x i64>
+  // CHECK: %splat.splat14 = shufflevector <2 x i64>
+
+  // vector float, double initialization
+  f1 = (vector float)17.5;
+  // CHECK: <float 1.750000e+01, float 1.750000e+01, float 1.750000e+01, float 1.750000e+01>
+  float f_temp = 20.2;
+  f2 = (vector float)f_temp;
+  // CHECK: %splat.splatinsert15 = insertelement <4 x float>
+  // CHECK: %splat.splat16 = shufflevector <4 x float>
+
+  d1 = (vector double)8.7;
+  // CHECK: <double 0x4021666666666666, double 0x4021666666666666>
+  double d_temp = 87.87;
+  d2 = (vector double)d_temp;
+  // CHECK: %splat.splatinsert17 = insertelement <2 x double>
+  // CHECK: %splat.splat18 = shufflevector <2 x double>
+}
Index: clang/test/CodeGen/vector-scalar-altivec-init.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/vector-scalar-altivec-init.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s
+
+vector char vi8_1;
+vector char vi8_2;
+vector unsigned char vui8_1;
+vector unsigned char vui8_2;
+
+vector short vi16_1;
+vector short vi16_2;
+vector unsigned short vui16_1;
+vector unsigned short vui16_2;
+
+vector int vi32_1;
+vector int vi32_2;
+vector unsigned int vui32_1;
+vector unsigned int vui32_2;
+
+vector long long vi64_1;
+vector long long vi64_2;
+vector unsigned long long vui64_1;
+vector unsigned long long vui64_2;
+
+vector float f1;
+vector float f2;
+vector double d1;
+vector double d2;
+
+////////////////////////////////////////////////////////////////////////////////
+void test_vector_scalar_init() {
+  // vector char initialization
+  vi8_1 = (vector char)('A');
+  // CHECK: <i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65>
+  char two = '2';
+  vi8_2 = (vector char)(two);
+  // CHECK: %splat.splatinsert = insertelement <16 x i8>
+  // CHECK: %splat.splat = shufflevector <16 x i8>
+
+  vui8_1 = (vector unsigned char)('B');
+  // CHECK: <i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66, i8 66>
+  unsigned char three = '3';
+  vui8_2 = (vector unsigned char)(three);
+  // CHECK: %splat.splatinsert1 = insertelement <16 x i8>
+  // CHECK: %splat.splat2 = shufflevector <16 x i8>
+
+  // vector short initialization
+  vi16_1 = (vector short)(5);
+  // CHECK: <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+  short six = 6;
+  vi16_2 = (vector short)(six);
+  // CHECK: %splat.splatinsert3 = insertelement <8 x i16>
+  // CHECK: %splat.splat4 = shufflevector <8 x i16>
+
+  vui16_1 = (vector unsigned short)(7);
+  // CHECK: <i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7>
+  unsigned short eight = 8;
+  vui16_2 = (vector unsigned short)(eight);
+  // CHECK: %splat.splatinsert5 = insertelement <8 x i16>
+  // CHECK: %splat.splat6 = shufflevector <8 x i16>
+
+  // vector int initialization
+  vi32_1 = (vector int)(9);
+  // CHECK: <i32 9, i32 9, i32 9, i32 9>
+  int ten = 10;
+  vi32_2 = (vector int)(ten);
+  // CHECK: %splat.splatinsert7 = insertelement <4 x i32>
+  // CHECK: %splat.splat8 = shufflevector <4 x i32>
+
+  vui32_1 = (vector unsigned int)(11);
+  // CHECK: <i32 11, i32 11, i32 11, i32 11>
+  unsigned int twelve = 12;
+  vui32_2 = (vector unsigned int)(twelve);
+  // CHECK: %splat.splatinsert9 = insertelement <4 x i32>
+  // CHECK: %splat.splat10 = shufflevector <4 x i32>
+
+  // vector long long initialization
+  vi64_1 = (vector long long)(143);
+  // CHECK: <i64 143, i64 143>
+  long long thousand = 1000;
+  vi64_1 = (vector long long)(thousand);
+  // CHECK: %splat.splatinsert11 = insertelement <2 x i64>
+  // CHECK: %splat.splat12 = shufflevector <2 x i64>
+
+  vui64_1 = (vector unsigned long long)(99);
+  // CHECK: <i64 99, i64 99>
+  unsigned long long twothousand = 2000;
+  vui64_1 = (vector unsigned long long)(twothousand);
+  // CHECK: %splat.splatinsert13 = insertelement <2 x i64>
+  // CHECK: %splat.splat14 = shufflevector <2 x i64>
+
+  // vector float, double initialization
+  f1 = (vector float)(17.5);
+  // CHECK: <float 1.750000e+01, float 1.750000e+01, float 1.750000e+01, float 1.750000e+01>
+  float f_temp = 20.2;
+  f2 = (vector float)(f_temp);
+  // CHECK: %splat.splatinsert15 = insertelement <4 x float>
+  // CHECK: %splat.splat16 = shufflevector <4 x float>
+
+  d1 = (vector double)(8.7);
+  // CHECK: <double 0x4021666666666666, double 0x4021666666666666>
+  double d_temp = 87.87;
+  d2 = (vector double)(d_temp);
+  // CHECK: %splat.splatinsert17 = insertelement <2 x double>
+  // CHECK: %splat.splat18 = shufflevector <2 x double>
+}
Index: clang/test/CodeGen/vector-bool-pixel-altivec-init2.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/vector-bool-pixel-altivec-init2.c
@@ -0,0 +1,85 @@
+// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED
+// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+// RUN: not %clang -mcpu=pwr8 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED
+// RUN: not %clang -mcpu=pwr9 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=MIXED
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+
+// Vector bool type
+vector bool char vbi8_1;
+vector bool char vbi8_2;
+
+vector bool short vbi16_1;
+vector bool short vbi16_2;
+
+vector bool int vbi32_1;
+vector bool int vbi32_2;
+
+vector bool long long vbi64_1;
+vector bool long long vbi64_2;
+
+// Vector pixel type
+vector pixel p1;
+
+////////////////////////////////////////////////////////////////////////////////
+void test_vector_bool_pixel_init() {
+  // vector bool char initialization
+  vbi8_1 = (vector bool char)'a';
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned char'
+  // XL: <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
+  char c = 'c';
+  vbi8_2 = (vector bool char)c;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned char'
+  // XL: %splat.splatinsert = insertelement <16 x i8>
+  // XL-NEXT: %splat.splat = shufflevector <16 x i8> %splat.splatinsert
+
+  // vector bool short initialization
+  vbi16_1 = (vector bool short)5;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned short'
+  // XL: <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+  short si16 = 55;
+  vbi16_2 = (vector bool short)si16;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned short'
+  // XL: %splat.splatinsert1 = insertelement <8 x i16>
+  // XL-NEXT: %splat.splat2 = shufflevector <8 x i16> %splat.splatinsert1
+
+  // vector bool int initialization
+  vbi32_1 = (vector bool int)9;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned int'
+  // XL: <i32 9, i32 9, i32 9, i32 9>
+  int si32 = 99;
+  vbi32_2 = (vector bool int)si32;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned int'
+  // XL: %splat.splatinsert3 = insertelement <4 x i32>
+  // XL-NEXT: %splat.splat4 = shufflevector <4 x i32> %splat.splatinsert3
+
+  // vector bool long long initialization
+  vbi64_1 = (vector bool long long)13;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned long long'
+  // XL: <i64 13, i64 13>
+  long long si64 = 1313;
+  vbi64_2 = (vector bool long long)si64;
+  // MIXED: error: invalid conversion between vector type '__vector __bool unsigned long long'
+  // XL: %splat.splatinsert5 = insertelement <2 x i64>
+  // XL-NEXT: %splat.splat6 = shufflevector <2 x i64> %splat.splatinsert5
+
+  // vector pixel initialization
+  p1 = (vector pixel)1;
+  // MIXED: error: invalid conversion between vector type '__vector __pixel '
+  // XL: <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+}
+
Index: clang/test/CodeGen/vector-bool-pixel-altivec-init.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/vector-bool-pixel-altivec-init.c
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=MIXED
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=mixed -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=MIXED
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
+// RUN:   -faltivec-src-compat=xl -triple powerpc64le-unknown-unknown -S \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s --check-prefix=MIXED
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=mixed --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s --check-prefix=MIXED
+// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown \
+// RUN:   -S -emit-llvm %s -o - | FileCheck %s --check-prefix=XL
+
+// Vector bool type
+vector bool char vbi8_1;
+vector bool char vbi8_2;
+
+vector bool short vbi16_1;
+vector bool short vbi16_2;
+
+vector bool int vbi32_1;
+vector bool int vbi32_2;
+
+vector bool long long vbi64_1;
+vector bool long long vbi64_2;
+
+// Vector pixel type
+vector pixel p1;
+
+////////////////////////////////////////////////////////////////////////////////
+void test_vector_bool_pixel_init() {
+  // vector bool char initialization
+  vbi8_1 = (vector bool char)('a');
+  // MIXED: <i8 97, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>
+  // XL: <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
+  char c = 'c';
+  vbi8_2 = (vector bool char)(c);
+  // MIXED: insertelement <16 x i8>
+  // XL: %splat.splatinsert = insertelement <16 x i8>
+  // XL-NEXT: %splat.splat = shufflevector <16 x i8> %splat.splatinsert
+
+  // vector bool short initialization
+  vbi16_1 = (vector bool short)(5);
+  // MIXED: <i16 5, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
+  // XL: <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
+  short si16 = 55;
+  vbi16_2 = (vector bool short)(si16);
+  // MIXED: insertelement <8 x i16>
+  // XL: %splat.splatinsert1 = insertelement <8 x i16>
+  // XL-NEXT: %splat.splat2 = shufflevector <8 x i16> %splat.splatinsert1
+
+  // vector bool int initialization
+  vbi32_1 = (vector bool int)(9);
+  // MIXED: <i32 9, i32 0, i32 0, i32 0>
+  // XL: <i32 9, i32 9, i32 9, i32 9>
+  int si32 = 99;
+  vbi32_2 = (vector bool int)(si32);
+  // MIXED: insertelement <4 x i32>
+  // XL: %splat.splatinsert3 = insertelement <4 x i32>
+  // XL-NEXT: %splat.splat4 = shufflevector <4 x i32> %splat.splatinsert3
+
+  // vector bool long long initialization
+  vbi64_1 = (vector bool long long)(13);
+  // MIXED: <i64 13, i64 0>
+  // XL: <i64 13, i64 13>
+  long long si64 = 1313;
+  vbi64_2 = (vector bool long long)(si64);
+  // MIXED: insertelement <2 x i64>
+  // XL: %splat.splatinsert5 = insertelement <2 x i64>
+  // XL-NEXT: %splat.splat6 = shufflevector <2 x i64> %splat.splatinsert5
+
+  // vector pixel initialization
+  p1 = (vector pixel)(1);
+  // MIXED: <i16 1, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
+  // XL: <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
+}
+
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -7707,7 +7707,7 @@
   // initializers must be one or must match the size of the vector.
   // If a single value is specified in the initializer then it will be
   // replicated to all the components of the vector
-  if (VTy->getVectorKind() == VectorType::AltiVecVector) {
+  if (ShouldSplatAltivecScalarInCast(*this, VTy)) {
     // The number of initializers must be one or must match the size of the
     // vector. If a single value is specified in the initializer then it will
     // be replicated to all the components of the vector
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -2624,6 +2624,23 @@
   }
 }
 
+// Checks if we have a valid AltiVec vector type, and splats the value into
+// the vector accordingly. If a 'vector bool' or 'vector pixel' type is used
+// with the -faltivec-src-compat=xl option, these types also splat the scalar
+// value into the respective vector (whereas normally they are not).
+bool Sema::ShouldSplatAltivecScalarInCast(Sema &Self, const VectorType *VecTy) {
+  bool SrcCompatXL = Self.getLangOpts().getAltivecSrcCompat() ==
+                     LangOptions::AltivecSrcCompatKind::XL;
+  VectorType::VectorKind VKind = VecTy->getVectorKind();
+
+  if ((VKind == VectorType::AltiVecVector) ||
+      (SrcCompatXL && ((VKind == VectorType::AltiVecBool) ||
+                       (VKind == VectorType::AltiVecPixel)))) {
+    return true;
+  }
+  return false;
+}
+
 void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
                                        bool ListInitialization) {
   assert(Self.getLangOpts().CPlusPlus);
@@ -2678,9 +2695,9 @@
 
   // AltiVec vector initialization with a single literal.
   if (const VectorType *vecTy = DestType->getAs<VectorType>())
-    if (vecTy->getVectorKind() == VectorType::AltiVecVector
-        && (SrcExpr.get()->getType()->isIntegerType()
-            || SrcExpr.get()->getType()->isFloatingType())) {
+    if (Self.ShouldSplatAltivecScalarInCast(Self, vecTy) &&
+        (SrcExpr.get()->getType()->isIntegerType() ||
+         SrcExpr.get()->getType()->isFloatingType())) {
       Kind = CK_VectorSplat;
       SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
       return;
@@ -2963,8 +2980,8 @@
   }
 
   if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) {
-    if (DestVecTy->getVectorKind() == VectorType::AltiVecVector &&
-          (SrcType->isIntegerType() || SrcType->isFloatingType())) {
+    if (Self.ShouldSplatAltivecScalarInCast(Self, DestVecTy) &&
+        (SrcType->isIntegerType() || SrcType->isFloatingType())) {
       Kind = CK_VectorSplat;
       SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
     } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6090,6 +6090,12 @@
   void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
                                       bool IsDereference, SourceRange Range);
 
+  // Checks if we have a valid AltiVec vector type, and splats the
+  // value into the vector accordingly. If a 'vector bool' or
+  // 'vector pixel' type is used with the -faltivec-src-compat=xl
+  // option, these types also splat the scalar value.
+  bool ShouldSplatAltivecScalarInCast(Sema &Self, const VectorType *VecTy);
+
   /// ActOnCXXNamedCast - Parse
   /// {dynamic,static,reinterpret,const,addrspace}_cast's.
   ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to