Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -120,7 +120,8 @@ LANGOPT(WritableStrings , 1, 0, "writable string support") LANGOPT(ConstStrings , 1, 0, "const-qualified string support") ENUM_LANGOPT(LaxVectorConversions, LaxVectorConversionKind, 2, - LaxVectorConversionKind::All, "lax vector conversions") + LaxVectorConversionKind::Integer, "lax vector conversions") +BENIGN_LANGOPT(LaxVectorConversionsSpecified, 1, 0, "whether lax vector conversions was specified") LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers") LANGOPT(ZVector , 1, 0, "System z vector extensions") LANGOPT(Exceptions , 1, 0, "exception handling") Index: lib/Basic/Targets/AArch64.h =================================================================== --- lib/Basic/Targets/AArch64.h +++ lib/Basic/Targets/AArch64.h @@ -57,6 +57,8 @@ return false; } + void adjust(LangOptions &Opts) override; + void getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const; void getTargetDefinesARMV82A(const LangOptions &Opts, Index: lib/Basic/Targets/AArch64.cpp =================================================================== --- lib/Basic/Targets/AArch64.cpp +++ lib/Basic/Targets/AArch64.cpp @@ -117,6 +117,17 @@ llvm::AArch64::fillValidCPUArchList(Values); } +void AArch64TargetInfo::adjust(LangOptions &Opts) { + TargetInfo::adjust(Opts); + + // FIXME: arm_neon.h makes use of lax vector conversions (including + // conversions between integer and floating-point type), so forcibly enable + // support for that language extension / bug whenever arm_neon.h would be + // usable. + if ((FPU & NeonMode) && !Opts.LaxVectorConversionsSpecified) + Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All); +} + void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); Index: lib/Basic/Targets/ARM.h =================================================================== --- lib/Basic/Targets/ARM.h +++ lib/Basic/Targets/ARM.h @@ -146,6 +146,8 @@ return false; } + void adjust(LangOptions &Opts) override; + void getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const; Index: lib/Basic/Targets/ARM.cpp =================================================================== --- lib/Basic/Targets/ARM.cpp +++ lib/Basic/Targets/ARM.cpp @@ -570,6 +570,18 @@ return false; } +void ARMTargetInfo::adjust(LangOptions &Opts) { + TargetInfo::adjust(Opts); + + // FIXME: arm_neon.h makes use of lax vector conversions (including + // conversions between integer and floating-point type), so forcibly enable + // support for that language extension / bug whenever arm_neon.h would be + // usable. + if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7 && + !Opts.LaxVectorConversionsSpecified) + Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All); +} + void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2669,6 +2669,7 @@ Opts.ConstStrings); if (Arg *A = Args.getLastArg(OPT_flax_vector_conversions_EQ)) { using LaxKind = LangOptions::LaxVectorConversionKind; + Opts.LaxVectorConversionsSpecified = true; if (auto Kind = llvm::StringSwitch>(A->getValue()) .Case("none", LaxKind::None) .Case("integer", LaxKind::Integer) Index: test/Headers/altivec-header.c =================================================================== --- test/Headers/altivec-header.c +++ test/Headers/altivec-header.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-feature +altivec -ffreestanding -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-feature +altivec -ffreestanding -emit-llvm -flax-vector-conversions=none -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-feature +altivec -ffreestanding -emit-llvm -flax-vector-conversions=all -o - %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-feature +altivec -ffreestanding -emit-llvm -x c++ -o - %s | FileCheck %s #include Index: test/Headers/arm-neon-header.c =================================================================== --- test/Headers/arm-neon-header.c +++ test/Headers/arm-neon-header.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversions -ffreestanding %s +// RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -flax-vector-conversions=all -Wvector-conversions -ffreestanding %s // RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -flax-vector-conversions=none -ffreestanding %s // RUN: %clang_cc1 -x c++ -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversions -ffreestanding %s Index: test/Headers/x86-intrinsics-headers.c =================================================================== --- test/Headers/x86-intrinsics-headers.c +++ test/Headers/x86-intrinsics-headers.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding %s +// RUN: %clang_cc1 -fsyntax-only -ffreestanding -flax-vector-conversions=all %s // RUN: %clang_cc1 -fsyntax-only -ffreestanding -flax-vector-conversions=none %s // RUN: %clang_cc1 -fsyntax-only -ffreestanding -x c++ %s Index: test/Headers/x86intrin-2.c =================================================================== --- test/Headers/x86intrin-2.c +++ test/Headers/x86intrin-2.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding %s -verify +// RUN: %clang_cc1 -fsyntax-only -ffreestanding -flax-vector-conversions=all %s -verify // RUN: %clang_cc1 -fsyntax-only -ffreestanding -flax-vector-conversions=none %s -verify // RUN: %clang_cc1 -fsyntax-only -ffreestanding -x c++ %s -verify // expected-no-diagnostics Index: test/Headers/x86intrin.c =================================================================== --- test/Headers/x86intrin.c +++ test/Headers/x86intrin.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding %s -verify +// RUN: %clang_cc1 -fsyntax-only -ffreestanding -flax-vector-conversions=all %s -verify // RUN: %clang_cc1 -fsyntax-only -ffreestanding -flax-vector-conversions=none %s -verify // RUN: %clang_cc1 -fsyntax-only -ffreestanding -x c++ %s -verify // expected-no-diagnostics Index: test/Sema/vector-assign.c =================================================================== --- test/Sema/vector-assign.c +++ test/Sema/vector-assign.c @@ -14,12 +14,12 @@ v1 = v2; // expected-warning {{incompatible vector types assigning to 'v2s' (vector of 2 'int' values) from 'v2u' (vector of 2 'unsigned int' values)}} v1 = v3; // expected-error {{assigning to 'v2s' (vector of 2 'int' values) from incompatible type 'v1s' (vector of 1 'int' value)}} - v1 = v4; // expected-warning {{incompatible vector types assigning to 'v2s' (vector of 2 'int' values) from 'v2f' (vector of 2 'float' values)}} + v1 = v4; // expected-error {{assigning to 'v2s' (vector of 2 'int' values) from incompatible type 'v2f' (vector of 2 'float' values)}} v1 = v5; // expected-warning {{incompatible vector types assigning to 'v2s' (vector of 2 'int' values) from 'v4ss' (vector of 4 'short' values)}} v2 = v1; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'v2s' (vector of 2 'int' values)}} v2 = v3; // expected-error {{assigning to 'v2u' (vector of 2 'unsigned int' values) from incompatible type 'v1s' (vector of 1 'int' value)}} - v2 = v4; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'v2f' (vector of 2 'float' values)}} + v2 = v4; // expected-error {{assigning to 'v2u' (vector of 2 'unsigned int' values) from incompatible type 'v2f' (vector of 2 'float' values)}} v2 = v5; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'v4ss' (vector of 4 'short' values)}} v3 = v1; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v2s' (vector of 2 'int' values)}} @@ -27,15 +27,15 @@ v3 = v4; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v2f' (vector of 2 'float' values)}} v3 = v5; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v4ss'}} - v4 = v1; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from 'v2s' (vector of 2 'int' values)}} - v4 = v2; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from 'v2u' (vector of 2 'unsigned int' values)}} + v4 = v1; // expected-error {{assigning to 'v2f' (vector of 2 'float' values) from incompatible type 'v2s' (vector of 2 'int' values)}} + v4 = v2; // expected-error {{assigning to 'v2f' (vector of 2 'float' values) from incompatible type 'v2u' (vector of 2 'unsigned int' values)}} v4 = v3; // expected-error {{assigning to 'v2f' (vector of 2 'float' values) from incompatible type 'v1s' (vector of 1 'int' value)}} - v4 = v5; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from 'v4ss' (vector of 4 'short' values)}} + v4 = v5; // expected-error {{assigning to 'v2f' (vector of 2 'float' values) from incompatible type 'v4ss' (vector of 4 'short' values)}} v5 = v1; // expected-warning {{incompatible vector types assigning to 'v4ss' (vector of 4 'short' values) from 'v2s' (vector of 2 'int' values)}} v5 = v2; // expected-warning {{incompatible vector types assigning to 'v4ss' (vector of 4 'short' values) from 'v2u' (vector of 2 'unsigned int' values)}} v5 = v3; // expected-error {{assigning to 'v4ss' (vector of 4 'short' values) from incompatible type 'v1s' (vector of 1 'int' value)}} - v5 = v4; // expected-warning {{incompatible vector types assigning to 'v4ss' (vector of 4 'short' values) from 'v2f'}} + v5 = v4; // expected-error {{assigning to 'v4ss' (vector of 4 'short' values) from incompatible type 'v2f'}} } // PR2263 Index: test/Sema/vector-cast.c =================================================================== --- test/Sema/vector-cast.c +++ test/Sema/vector-cast.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only %s -verify -Wvector-conversion +// RUN: %clang_cc1 -fsyntax-only %s -verify -Wvector-conversion -flax-vector-conversions=all typedef long long t1 __attribute__ ((vector_size (8))); typedef char t2 __attribute__ ((vector_size (16))); Index: test/Sema/vector-ops.c =================================================================== --- test/Sema/vector-ops.c +++ test/Sema/vector-ops.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversion -triple x86_64-apple-darwin10 +// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversion -triple x86_64-apple-darwin10 -flax-vector-conversions=all typedef unsigned int v2u __attribute__ ((vector_size (8))); typedef int v2s __attribute__ ((vector_size (8))); typedef float v2f __attribute__ ((vector_size(8)));