Author: Joseph Huber
Date: 2025-08-20T07:49:26-05:00
New Revision: 5a929a42496c58cdf8bde8e80f2d950a3f1a182d

URL: 
https://github.com/llvm/llvm-project/commit/5a929a42496c58cdf8bde8e80f2d950a3f1a182d
DIFF: 
https://github.com/llvm/llvm-project/commit/5a929a42496c58cdf8bde8e80f2d950a3f1a182d.diff

LOG: [Clang] Support using boolean vectors in ternary operators (#154145)

Summary:
It's extremely common to conditionally blend two vectors. Previously
this was done with mask registers, which is what the normal ternary code
generation does when used on a vector. However, since Clang 15 we have
supported boolean vector types in the compiler. These are useful in
general for checking the mask registers, but are currently limited
because they do not map to an LLVM-IR select instruction.

This patch simply relaxes these checks, which are technically forbidden
by
the OpenCL standard. However, general vector support should be able to
handle these. We already support this for Arm SVE types, so this should
be make more consistent with the clang vector type.

Added: 
    

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/docs/ReleaseNotes.rst
    clang/lib/CodeGen/CGExprScalar.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/test/CodeGenCXX/aarch64-sve-vector-conditional-op.cpp
    clang/test/CodeGenCXX/ext-vector-type-conditional.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 66ac22349367a..12ca4cf42f7cc 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -657,6 +657,16 @@ The size and alignment are both the number of bits rounded 
up to the next power
 of two, but the alignment is at most the maximum vector alignment of the
 target.
 
+A boolean vector can be used in a ternary `?:` operator to select vector
+elements of a 
diff erent type.
+
+.. code-block:: c++
+
+  typedef int int4 __attribute__((ext_vector_type(4)));
+  typedef bool bool4 __attribute__((ext_vector_type(4)));
+
+  int4 blend(bool4 cond, int4 a, int4 b) { return cond ? a : b; }
+
 
 Vector Literals
 ---------------

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5c780851ca589..e88d68fa99664 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -137,12 +137,14 @@ Non-comprehensive list of changes in this release
 - ``__builtin_elementwise_max`` and ``__builtin_elementwise_min`` functions 
for integer types can
   now be used in constant expressions.
 
+- A vector of booleans is now a valid condition for the ternary ``?:`` 
operator.
+  This binds to a simple vector select operation.
+
 - Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and 
``ptrauth_intrinsics``
   features has been deprecated, and is restricted to the arm64e target only. 
The
   correct method to check for these features is to test for the ``__PTRAUTH__``
   macro.
 
-
 New Compiler Flags
 ------------------
 - New option ``-fno-sanitize-annotate-debug-info-traps`` added to disable 
emitting trap reasons into the debug info when compiling with trapping UBSan 
(e.g. ``-fsanitize-trap=undefined``).

diff  --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 155b80df36715..fcbfa5e31d149 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5558,8 +5558,8 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 
   // OpenCL: If the condition is a vector, we can treat this condition like
   // the select function.
-  if ((CGF.getLangOpts().OpenCL && condExpr->getType()->isVectorType()) ||
-      condExpr->getType()->isExtVectorType()) {
+  if (CGF.getLangOpts().OpenCL && (condExpr->getType()->isVectorType() ||
+                                   condExpr->getType()->isExtVectorType())) {
     CGF.incrementProfileCounter(E);
 
     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
@@ -5608,9 +5608,16 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 
     llvm::Type *CondType = ConvertType(condExpr->getType());
     auto *VecTy = cast<llvm::VectorType>(CondType);
-    llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
 
-    CondV = Builder.CreateICmpNE(CondV, ZeroVec, "vector_cond");
+    if (VecTy->getElementType()->isIntegerTy(1))
+      return Builder.CreateSelect(CondV, LHS, RHS, "vector_select");
+
+    // OpenCL uses the MSB of the mask vector.
+    llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
+    if (condExpr->getType()->isExtVectorType())
+      CondV = Builder.CreateICmpSLT(CondV, ZeroVec, "vector_cond");
+    else
+      CondV = Builder.CreateICmpNE(CondV, ZeroVec, "vector_cond");
     return Builder.CreateSelect(CondV, LHS, RHS, "vector_select");
   }
 

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 265cd799373a5..dcd70e6769e23 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8434,9 +8434,11 @@ static bool checkVectorResult(Sema &S, QualType CondTy, 
QualType VecResTy,
   QualType CVE = CV->getElementType();
   QualType RVE = RV->getElementType();
 
-  if (S.Context.getTypeSize(CVE) != S.Context.getTypeSize(RVE)) {
+  // Boolean vectors are permitted outside of OpenCL mode.
+  if (S.Context.getTypeSize(CVE) != S.Context.getTypeSize(RVE) &&
+      (!CVE->isBooleanType() || S.LangOpts.OpenCL)) {
     S.Diag(QuestionLoc, diag::err_conditional_vector_element_size)
-      << CondTy << VecResTy;
+        << CondTy << VecResTy;
     return true;
   }
 

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 7ab1cda1925f9..2a82842095446 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5753,10 +5753,12 @@ QualType Sema::CheckVectorConditionalTypes(ExprResult 
&Cond, ExprResult &LHS,
     return {};
   }
 
+  // Boolean vectors are permitted outside of OpenCL mode.
   if (Context.getTypeSize(ResultElementTy) !=
-      Context.getTypeSize(CondElementTy)) {
-    Diag(QuestionLoc, diag::err_conditional_vector_element_size) << CondType
-                                                                 << ResultType;
+          Context.getTypeSize(CondElementTy) &&
+      (!CondElementTy->isBooleanType() || LangOpts.OpenCL)) {
+    Diag(QuestionLoc, diag::err_conditional_vector_element_size)
+        << CondType << ResultType;
     return {};
   }
 

diff  --git a/clang/test/CodeGenCXX/aarch64-sve-vector-conditional-op.cpp 
b/clang/test/CodeGenCXX/aarch64-sve-vector-conditional-op.cpp
index d6fa26bd34099..5c99393357425 100644
--- a/clang/test/CodeGenCXX/aarch64-sve-vector-conditional-op.cpp
+++ b/clang/test/CodeGenCXX/aarch64-sve-vector-conditional-op.cpp
@@ -10,8 +10,7 @@
 // CHECK-LABEL: @_Z9cond_boolu10__SVBool_tS_(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[CMP:%.*]] = icmp ult <vscale x 16 x i1> [[A:%.*]], 
[[B:%.*]]
-// CHECK-NEXT:    [[VECTOR_COND:%.*]] = icmp ne <vscale x 16 x i1> [[CMP]], 
zeroinitializer
-// CHECK-NEXT:    [[VECTOR_SELECT:%.*]] = select <vscale x 16 x i1> 
[[VECTOR_COND]], <vscale x 16 x i1> [[A]], <vscale x 16 x i1> [[B]]
+// CHECK-NEXT:    [[VECTOR_SELECT:%.*]] = select <vscale x 16 x i1> [[CMP]], 
<vscale x 16 x i1> [[A]], <vscale x 16 x i1> [[B]]
 // CHECK-NEXT:    ret <vscale x 16 x i1> [[VECTOR_SELECT]]
 //
 svbool_t cond_bool(svbool_t a, svbool_t b) {

diff  --git a/clang/test/CodeGenCXX/ext-vector-type-conditional.cpp 
b/clang/test/CodeGenCXX/ext-vector-type-conditional.cpp
index 4504000856f23..8ef3fbb5378d7 100644
--- a/clang/test/CodeGenCXX/ext-vector-type-conditional.cpp
+++ b/clang/test/CodeGenCXX/ext-vector-type-conditional.cpp
@@ -1,3 +1,4 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
 // RUN: %clang_cc1 %s -triple x86_64-linux-gnu -Wno-unused -std=c++11 
-emit-llvm -o - | FileCheck %s
 
 using FourShorts = short __attribute__((ext_vector_type(4)));
@@ -11,6 +12,7 @@ using TwoFloats = float __attribute__((ext_vector_type(2)));
 using FourFloats = float __attribute__((ext_vector_type(4)));
 using TwoDoubles = double __attribute__((ext_vector_type(2)));
 using FourDoubles = double __attribute__((ext_vector_type(4)));
+using TwoBools = bool __attribute__((ext_vector_type(2)));
 
 FourShorts four_shorts;
 TwoInts two_ints;
@@ -23,6 +25,7 @@ TwoFloats two_floats;
 FourFloats four_floats;
 TwoDoubles two_doubles;
 FourDoubles four_doubles;
+TwoBools two_bools;
 
 short some_short;
 unsigned short some_ushort;
@@ -33,235 +36,186 @@ long long some_ll;
 unsigned long long some_ull;
 double some_double;
 
-// CHECK: TwoVectorOps
+// CHECK-LABEL: define dso_local void @_Z12TwoVectorOpsv(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i32>, ptr @two_ints, align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i32>, ptr @two_ints, align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i32>, ptr @two_ints, align 8
+// CHECK-NEXT:    [[VECTOR_COND:%.*]] = icmp slt <2 x i32> [[TMP0]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT:%.*]] = select <2 x i1> [[VECTOR_COND]], <2 
x i32> [[TMP1]], <2 x i32> [[TMP2]]
+// CHECK-NEXT:    [[TMP3:%.*]] = load <2 x i32>, ptr @two_ints, align 8
+// CHECK-NEXT:    [[TMP4:%.*]] = load <2 x float>, ptr @two_floats, align 8
+// CHECK-NEXT:    [[TMP5:%.*]] = load <2 x float>, ptr @two_floats, align 8
+// CHECK-NEXT:    [[VECTOR_COND1:%.*]] = icmp slt <2 x i32> [[TMP3]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT2:%.*]] = select <2 x i1> [[VECTOR_COND1]], 
<2 x float> [[TMP4]], <2 x float> [[TMP5]]
+// CHECK-NEXT:    [[TMP6:%.*]] = load <2 x i64>, ptr @two_ll, align 16
+// CHECK-NEXT:    [[TMP7:%.*]] = load <2 x double>, ptr @two_doubles, align 16
+// CHECK-NEXT:    [[TMP8:%.*]] = load <2 x double>, ptr @two_doubles, align 16
+// CHECK-NEXT:    [[VECTOR_COND3:%.*]] = icmp slt <2 x i64> [[TMP6]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT4:%.*]] = select <2 x i1> [[VECTOR_COND3]], 
<2 x double> [[TMP7]], <2 x double> [[TMP8]]
+// CHECK-NEXT:    [[LOAD_BITS:%.*]] = load i8, ptr @two_bools, align 1
+// CHECK-NEXT:    [[TMP9:%.*]] = bitcast i8 [[LOAD_BITS]] to <8 x i1>
+// CHECK-NEXT:    [[EXTRACTVEC:%.*]] = shufflevector <8 x i1> [[TMP9]], <8 x 
i1> poison, <2 x i32> <i32 0, i32 1>
+// CHECK-NEXT:    [[TMP10:%.*]] = load <2 x i32>, ptr @two_ints, align 8
+// CHECK-NEXT:    [[TMP11:%.*]] = load <2 x i32>, ptr @two_ints, align 8
+// CHECK-NEXT:    [[VECTOR_SELECT5:%.*]] = select <2 x i1> [[EXTRACTVEC]], <2 
x i32> [[TMP10]], <2 x i32> [[TMP11]]
+// CHECK-NEXT:    [[LOAD_BITS6:%.*]] = load i8, ptr @two_bools, align 1
+// CHECK-NEXT:    [[TMP12:%.*]] = bitcast i8 [[LOAD_BITS6]] to <8 x i1>
+// CHECK-NEXT:    [[EXTRACTVEC7:%.*]] = shufflevector <8 x i1> [[TMP12]], <8 x 
i1> poison, <2 x i32> <i32 0, i32 1>
+// CHECK-NEXT:    [[TMP13:%.*]] = load <2 x double>, ptr @two_doubles, align 16
+// CHECK-NEXT:    [[TMP14:%.*]] = load <2 x double>, ptr @two_doubles, align 16
+// CHECK-NEXT:    [[VECTOR_SELECT8:%.*]] = select <2 x i1> [[EXTRACTVEC7]], <2 
x double> [[TMP13]], <2 x double> [[TMP14]]
+// CHECK-NEXT:    ret void
+//
 void TwoVectorOps() {
   two_ints ? two_ints : two_ints;
-  // CHECK: [[COND:%.+]] = load <2 x i32>
-  // CHECK: [[LHS:%.+]] = load <2 x i32>
-  // CHECK: [[RHS:%.+]] = load <2 x i32>
-  // CHECK: [[NEG:%.+]] = icmp slt <2 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <2 x i1> [[NEG]] to <2 x i32>
-  // CHECK: [[XOR:%.+]] = xor <2 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <2 x i32> [[RHS]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <2 x i32> [[LHS]], [[SEXT]]
-  // CHECK: = or <2 x i32> [[RHS_AND]], [[LHS_AND]]
 
   two_ints ? two_floats : two_floats;
-  // CHECK: [[COND:%.+]] = load <2 x i32>
-  // CHECK: [[LHS:%.+]] = load <2 x float>
-  // CHECK: [[RHS:%.+]] = load <2 x float>
-  // CHECK: [[NEG:%.+]] = icmp slt <2 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <2 x i1> [[NEG]] to <2 x i32>
-  // CHECK: [[XOR:%.+]] = xor <2 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_EXT:%.+]] = bitcast <2 x float> [[RHS]] to <2 x i32>
-  // CHECK: [[LHS_EXT:%.+]] = bitcast <2 x float> [[LHS]] to <2 x i32>
-  // CHECK: [[RHS_AND:%.+]] = and <2 x i32> [[RHS_EXT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <2 x i32> [[LHS_EXT]], [[SEXT]]
-  // CHECK: [[OR:%.+]] = or <2 x i32> [[RHS_AND]], [[LHS_AND]]
-  // CHECK: = bitcast <2 x i32> [[OR]] to <2 x float>
 
   two_ll ? two_doubles : two_doubles;
-  // CHECK: [[COND:%.+]] = load <2 x i64>
-  // CHECK: [[LHS:%.+]] = load <2 x double>
-  // CHECK: [[RHS:%.+]] = load <2 x double>
-  // CHECK: [[NEG:%.+]] = icmp slt <2 x i64> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <2 x i1> [[NEG]] to <2 x i64>
-  // CHECK: [[XOR:%.+]] = xor <2 x i64> [[SEXT]], splat (i64 -1)
-  // CHECK: [[RHS_EXT:%.+]] = bitcast <2 x double> [[RHS]] to <2 x i64>
-  // CHECK: [[LHS_EXT:%.+]] = bitcast <2 x double> [[LHS]] to <2 x i64>
-  // CHECK: [[RHS_AND:%.+]] = and <2 x i64> [[RHS_EXT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <2 x i64> [[LHS_EXT]], [[SEXT]]
-  // CHECK: [[OR:%.+]] = or <2 x i64> [[RHS_AND]], [[LHS_AND]]
-  // CHECK: = bitcast <2 x i64> [[OR]] to <2 x double>
+
+  two_bools ? two_ints : two_ints;
+
+  two_bools ? two_doubles : two_doubles;
 }
 
-// CHECK: TwoScalarOps
+// CHECK-LABEL: define dso_local void @_Z12TwoScalarOpsv(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i16>, ptr @four_shorts, align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr @some_short, align 2
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT:%.*]] = insertelement <4 x i16> poison, 
i16 [[TMP1]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT:%.*]] = shufflevector <4 x i16> 
[[SPLAT_SPLATINSERT]], <4 x i16> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[TMP2:%.*]] = load i16, ptr @some_short, align 2
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT1:%.*]] = insertelement <4 x i16> poison, 
i16 [[TMP2]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT2:%.*]] = shufflevector <4 x i16> 
[[SPLAT_SPLATINSERT1]], <4 x i16> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND:%.*]] = icmp slt <4 x i16> [[TMP0]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT:%.*]] = select <4 x i1> [[VECTOR_COND]], <4 
x i16> [[SPLAT_SPLAT]], <4 x i16> [[SPLAT_SPLAT2]]
+// CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i16>, ptr @four_shorts, align 8
+// CHECK-NEXT:    [[TMP4:%.*]] = load i16, ptr @some_ushort, align 2
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT3:%.*]] = insertelement <4 x i16> poison, 
i16 [[TMP4]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT4:%.*]] = shufflevector <4 x i16> 
[[SPLAT_SPLATINSERT3]], <4 x i16> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[TMP5:%.*]] = load i16, ptr @some_ushort, align 2
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT5:%.*]] = insertelement <4 x i16> poison, 
i16 [[TMP5]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT6:%.*]] = shufflevector <4 x i16> 
[[SPLAT_SPLATINSERT5]], <4 x i16> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND7:%.*]] = icmp slt <4 x i16> [[TMP3]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT8:%.*]] = select <4 x i1> [[VECTOR_COND7]], 
<4 x i16> [[SPLAT_SPLAT4]], <4 x i16> [[SPLAT_SPLAT6]]
+// CHECK-NEXT:    [[TMP6:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP7:%.*]] = load i16, ptr @some_ushort, align 2
+// CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[TMP7]] to i32
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT9:%.*]] = insertelement <4 x i32> poison, 
i32 [[CONV]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT10:%.*]] = shufflevector <4 x i32> 
[[SPLAT_SPLATINSERT9]], <4 x i32> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[TMP8:%.*]] = load i16, ptr @some_short, align 2
+// CHECK-NEXT:    [[CONV11:%.*]] = sext i16 [[TMP8]] to i32
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT12:%.*]] = insertelement <4 x i32> 
poison, i32 [[CONV11]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT13:%.*]] = shufflevector <4 x i32> 
[[SPLAT_SPLATINSERT12]], <4 x i32> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND14:%.*]] = icmp slt <4 x i32> [[TMP6]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT15:%.*]] = select <4 x i1> [[VECTOR_COND14]], 
<4 x i32> [[SPLAT_SPLAT10]], <4 x i32> [[SPLAT_SPLAT13]]
+// CHECK-NEXT:    [[TMP9:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr @some_int, align 4
+// CHECK-NEXT:    [[CONV16:%.*]] = sitofp i32 [[TMP10]] to float
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT17:%.*]] = insertelement <4 x float> 
poison, float [[CONV16]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT18:%.*]] = shufflevector <4 x float> 
[[SPLAT_SPLATINSERT17]], <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[TMP11:%.*]] = load float, ptr @some_float, align 4
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT19:%.*]] = insertelement <4 x float> 
poison, float [[TMP11]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT20:%.*]] = shufflevector <4 x float> 
[[SPLAT_SPLATINSERT19]], <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND21:%.*]] = icmp slt <4 x i32> [[TMP9]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT22:%.*]] = select <4 x i1> [[VECTOR_COND21]], 
<4 x float> [[SPLAT_SPLAT18]], <4 x float> [[SPLAT_SPLAT20]]
+// CHECK-NEXT:    [[TMP12:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP13:%.*]] = load double, ptr @some_double, align 8
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT23:%.*]] = insertelement <4 x double> 
poison, double [[TMP13]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT24:%.*]] = shufflevector <4 x double> 
[[SPLAT_SPLATINSERT23]], <4 x double> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[TMP14:%.*]] = load i64, ptr @some_ll, align 8
+// CHECK-NEXT:    [[CONV25:%.*]] = sitofp i64 [[TMP14]] to double
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT26:%.*]] = insertelement <4 x double> 
poison, double [[CONV25]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT27:%.*]] = shufflevector <4 x double> 
[[SPLAT_SPLATINSERT26]], <4 x double> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND28:%.*]] = icmp slt <4 x i64> [[TMP12]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT29:%.*]] = select <4 x i1> [[VECTOR_COND28]], 
<4 x double> [[SPLAT_SPLAT24]], <4 x double> [[SPLAT_SPLAT27]]
+// CHECK-NEXT:    [[TMP15:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP16:%.*]] = load i32, ptr @some_int, align 4
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT30:%.*]] = insertelement <4 x i32> 
poison, i32 [[TMP16]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT31:%.*]] = shufflevector <4 x i32> 
[[SPLAT_SPLATINSERT30]], <4 x i32> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[TMP17:%.*]] = load i16, ptr @some_short, align 2
+// CHECK-NEXT:    [[CONV32:%.*]] = sext i16 [[TMP17]] to i32
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT33:%.*]] = insertelement <4 x i32> 
poison, i32 [[CONV32]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT34:%.*]] = shufflevector <4 x i32> 
[[SPLAT_SPLATINSERT33]], <4 x i32> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND35:%.*]] = icmp slt <4 x i32> [[TMP15]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT36:%.*]] = select <4 x i1> [[VECTOR_COND35]], 
<4 x i32> [[SPLAT_SPLAT31]], <4 x i32> [[SPLAT_SPLAT34]]
+// CHECK-NEXT:    ret void
+//
 void TwoScalarOps() {
   four_shorts ? some_short : some_short;
-  // CHECK: [[COND:%.+]] = load <4 x i16>
-  // CHECK: [[LHS:%.+]] = load i16
-  // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 
[[LHS]], i64 0
-  // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i16> [[LHS_SPLAT_INSERT]], 
<4 x i16> poison, <4 x i32> zeroinitializer
-  // CHECK: [[RHS:%.+]] = load i16
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 
[[RHS]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i16> [[RHS_SPLAT_INSERT]], 
<4 x i16> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i16> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i16>
-  // CHECK: [[XOR:%.+]] = xor <4 x i16> [[SEXT]], splat (i16 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i16> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i16> [[LHS_SPLAT]], [[SEXT]]
-  // CHECK: = or <4 x i16> [[RHS_AND]], [[LHS_AND]]
 
   four_shorts ? some_ushort : some_ushort;
-  // CHECK: [[COND:%.+]] = load <4 x i16>
-  // CHECK: [[LHS:%.+]] = load i16
-  // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 
[[LHS]], i64 0
-  // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i16> [[LHS_SPLAT_INSERT]], 
<4 x i16> poison, <4 x i32> zeroinitializer
-  // CHECK: [[RHS:%.+]] = load i16
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i16> poison, i16 
[[RHS]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i16> [[RHS_SPLAT_INSERT]], 
<4 x i16> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i16> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i16>
-  // CHECK: [[XOR:%.+]] = xor <4 x i16> [[SEXT]], splat (i16 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i16> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i16> [[LHS_SPLAT]], [[SEXT]]
-  // CHECK: = or <4 x i16> [[RHS_AND]], [[LHS_AND]]
 
   four_ints ? some_ushort : some_short;
-  // CHECK: [[COND:%.+]] = load <4 x i32>
-  // CHECK: [[LHS:%.+]] = load i16
-  // CHECK: [[LHS_ZEXT:%.+]] = zext i16 [[LHS]] to i32
-  // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 
[[LHS_ZEXT]], i64 0
-  // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i32> [[LHS_SPLAT_INSERT]], 
<4 x i32> poison, <4 x i32> zeroinitializer
-  // CHECK: [[RHS:%.+]] = load i16
-  // CHECK: [[RHS_SEXT:%.+]] = sext i16 [[RHS]] to i32
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 
[[RHS_SEXT]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i32> [[RHS_SPLAT_INSERT]], 
<4 x i32> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
-  // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_SPLAT]], [[SEXT]]
-  // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
 
   four_ints ? some_int : some_float;
-  // CHECK: [[COND:%.+]] = load <4 x i32>
-  // CHECK: [[LHS:%.+]] = load i32
-  // CHECK: [[LHS_CONV:%.+]] = sitofp i32 [[LHS]] to float
-  // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x float> poison, float 
[[LHS_CONV]], i64 0
-  // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x float> 
[[LHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer
-  // CHECK: [[RHS:%.+]] = load float
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x float> poison, float 
[[RHS]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x float> 
[[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
-  // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_CAST:%.+]] = bitcast <4 x float> [[RHS_SPLAT]] to <4 x i32>
-  // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x float> [[LHS_SPLAT]] to <4 x i32>
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_CAST]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_CAST]], [[SEXT]]
-  // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
 
   four_ll ? some_double : some_ll;
-  // CHECK: [[COND:%.+]] = load <4 x i64>
-  // CHECK: [[LHS:%.+]] = load double
-  // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x double> poison, 
double [[LHS]], i64 0
-  // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x double> 
[[LHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer
-  // CHECK: [[RHS:%.+]] = load i64
-  // CHECK: [[RHS_CONV:%.+]] = sitofp i64 [[RHS]] to double
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x double> poison, 
double [[RHS_CONV]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x double> 
[[RHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
-  // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1)
-  // CHECK: [[RHS_CAST:%.+]] = bitcast <4 x double> [[RHS_SPLAT]] to <4 x i64>
-  // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x double> [[LHS_SPLAT]] to <4 x i64>
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[RHS_CAST]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS_CAST]], [[SEXT]]
-  // CHECK: = or <4 x i64> [[RHS_AND]], [[LHS_AND]]
 
   four_ints ? some_int : some_short;
-  // CHECK: [[COND:%.+]] = load <4 x i32>
-  // CHECK: [[LHS:%.+]] = load i32
-  // CHECK: [[LHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 
[[LHS]], i64 0
-  // CHECK: [[LHS_SPLAT:%.+]] = shufflevector <4 x i32> [[LHS_SPLAT_INSERT]], 
<4 x i32> poison, <4 x i32> zeroinitializer
-  // CHECK: [[RHS:%.+]] = load i16
-  // CHECK: [[RHS_SEXT:%.+]] = sext i16 [[RHS]] to i32
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 
[[RHS_SEXT]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i32> [[RHS_SPLAT_INSERT]], 
<4 x i32> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
-  // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_SPLAT]], [[SEXT]]
-  // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
 }
 
-// CHECK: OneScalarOp
+// CHECK-LABEL: define dso_local void @_Z11OneScalarOpv(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr @some_int, align 4
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, 
i32 [[TMP2]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT:%.*]] = shufflevector <4 x i32> 
[[SPLAT_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND:%.*]] = icmp slt <4 x i32> [[TMP0]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT:%.*]] = select <4 x i1> [[VECTOR_COND]], <4 
x i32> [[TMP1]], <4 x i32> [[SPLAT_SPLAT]]
+// CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP4:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[VECTOR_COND1:%.*]] = icmp slt <4 x i32> [[TMP3]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT2:%.*]] = select <4 x i1> [[VECTOR_COND1]], 
<4 x i32> [[TMP4]], <4 x i32> splat (i32 5)
+// CHECK-NEXT:    [[TMP5:%.*]] = load <4 x i32>, ptr @four_ints, align 16
+// CHECK-NEXT:    [[TMP6:%.*]] = load <4 x float>, ptr @four_floats, align 16
+// CHECK-NEXT:    [[TMP7:%.*]] = load float, ptr @some_float, align 4
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT3:%.*]] = insertelement <4 x float> 
poison, float [[TMP7]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT4:%.*]] = shufflevector <4 x float> 
[[SPLAT_SPLATINSERT3]], <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND5:%.*]] = icmp slt <4 x i32> [[TMP5]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT6:%.*]] = select <4 x i1> [[VECTOR_COND5]], 
<4 x float> [[TMP6]], <4 x float> [[SPLAT_SPLAT4]]
+// CHECK-NEXT:    [[TMP8:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP9:%.*]] = load <4 x double>, ptr @four_doubles, align 32
+// CHECK-NEXT:    [[VECTOR_COND7:%.*]] = icmp slt <4 x i64> [[TMP8]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT8:%.*]] = select <4 x i1> [[VECTOR_COND7]], 
<4 x double> [[TMP9]], <4 x double> splat (double 6.000000e+00)
+// CHECK-NEXT:    [[TMP10:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP11:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[VECTOR_COND9:%.*]] = icmp slt <4 x i64> [[TMP10]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT10:%.*]] = select <4 x i1> [[VECTOR_COND9]], 
<4 x i64> [[TMP11]], <4 x i64> splat (i64 6)
+// CHECK-NEXT:    [[TMP12:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP13:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr @some_int, align 4
+// CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP14]] to i64
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT11:%.*]] = insertelement <4 x i64> 
poison, i64 [[CONV]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT12:%.*]] = shufflevector <4 x i64> 
[[SPLAT_SPLATINSERT11]], <4 x i64> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND13:%.*]] = icmp slt <4 x i64> [[TMP12]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT14:%.*]] = select <4 x i1> [[VECTOR_COND13]], 
<4 x i64> [[TMP13]], <4 x i64> [[SPLAT_SPLAT12]]
+// CHECK-NEXT:    [[TMP15:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP16:%.*]] = load <4 x i64>, ptr @four_ll, align 32
+// CHECK-NEXT:    [[TMP17:%.*]] = load i64, ptr @some_ll, align 8
+// CHECK-NEXT:    [[SPLAT_SPLATINSERT15:%.*]] = insertelement <4 x i64> 
poison, i64 [[TMP17]], i64 0
+// CHECK-NEXT:    [[SPLAT_SPLAT16:%.*]] = shufflevector <4 x i64> 
[[SPLAT_SPLATINSERT15]], <4 x i64> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:    [[VECTOR_COND17:%.*]] = icmp slt <4 x i64> [[TMP15]], 
zeroinitializer
+// CHECK-NEXT:    [[VECTOR_SELECT18:%.*]] = select <4 x i1> [[VECTOR_COND17]], 
<4 x i64> [[TMP16]], <4 x i64> [[SPLAT_SPLAT16]]
+// CHECK-NEXT:    ret void
+//
 void OneScalarOp() {
   four_ints ? four_ints : some_int;
-  // CHECK: [[COND:%.+]] = load <4 x i32>
-  // CHECK: [[LHS:%.+]] = load <4 x i32>
-  // CHECK: [[RHS:%.+]] = load i32
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i32> poison, i32 
[[RHS]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i32> [[RHS_SPLAT_INSERT]], 
<4 x i32> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
-  // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS]], [[SEXT]]
-  // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
 
   four_ints ? four_ints : 5;
-  // CHECK: [[COND:%.+]] = load <4 x i32>
-  // CHECK: [[LHS:%.+]] = load <4 x i32>
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
-  // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i32> splat (i32 5), [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS]], [[SEXT]]
-  // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
 
   four_ints ? four_floats : some_float;
-  // CHECK: [[COND:%.+]] = load <4 x i32>
-  // CHECK: [[LHS:%.+]] = load <4 x float>
-  // CHECK: [[RHS:%.+]] = load float
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x float> poison, float 
[[RHS]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x float> 
[[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i32> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i32>
-  // CHECK: [[XOR:%.+]] = xor <4 x i32> [[SEXT]], splat (i32 -1)
-  // CHECK: [[RHS_CAST:%.+]] = bitcast <4 x float> [[RHS_SPLAT]] to <4 x i32>
-  // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x float> [[LHS]] to <4 x i32>
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i32> [[RHS_CAST]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i32> [[LHS_CAST]], [[SEXT]]
-  // CHECK: = or <4 x i32> [[RHS_AND]], [[LHS_AND]]
 
   four_ll ? four_doubles : 6.0;
-  // CHECK: [[COND:%.+]] = load <4 x i64>
-  // CHECK: [[LHS:%.+]] = load <4 x double>
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
-  // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1)
-  // CHECK: [[LHS_CAST:%.+]] = bitcast <4 x double> [[LHS]] to <4 x i64>
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i64> splat (i64 4618441417868443648), 
[[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS_CAST]], [[SEXT]]
-  // CHECK: = or <4 x i64> [[RHS_AND]], [[LHS_AND]]
 
   four_ll ? four_ll : 6;
-  // CHECK: [[COND:%.+]] = load <4 x i64>
-  // CHECK: [[LHS:%.+]] = load <4 x i64>
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
-  // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i64> splat (i64 6), [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]]
-  // CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]]
 
   four_ll ? four_ll : some_int;
-  // CHECK: [[COND:%.+]] = load <4 x i64>
-  // CHECK: [[LHS:%.+]] = load <4 x i64>
-  // CHECK: [[RHS:%.+]] = load i32
-  // CHECK: [[RHS_CONV:%.+]] = sext i32 [[RHS]] to i64
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i64> poison, i64 
[[RHS_CONV]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i64> [[RHS_SPLAT_INSERT]], 
<4 x i64> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
-  // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]]
-  // CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]]
 
   four_ll ? four_ll : some_ll;
-  // CHECK: [[COND:%.+]] = load <4 x i64>
-  // CHECK: [[LHS:%.+]] = load <4 x i64>
-  // CHECK: [[RHS:%.+]] = load i64
-  // CHECK: [[RHS_SPLAT_INSERT:%.+]] = insertelement <4 x i64> poison, i64 
[[RHS]], i64 0
-  // CHECK: [[RHS_SPLAT:%.+]] = shufflevector <4 x i64> [[RHS_SPLAT_INSERT]], 
<4 x i64> poison, <4 x i32> zeroinitializer
-  // CHECK: [[NEG:%.+]] = icmp slt <4 x i64> [[COND]], zeroinitializer
-  // CHECK: [[SEXT:%.+]] = sext <4 x i1> [[NEG]] to <4 x i64>
-  // CHECK: [[XOR:%.+]] = xor <4 x i64> [[SEXT]], splat (i64 -1)
-  // CHECK: [[RHS_AND:%.+]] = and <4 x i64> [[RHS_SPLAT]], [[XOR]]
-  // CHECK: [[LHS_AND:%.+]] = and <4 x i64> [[LHS]], [[SEXT]]
-  // CHECK: [[OR:%.+]] = or <4 x i64> [[RHS_AND]], [[LHS_AND]]
 }


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to