[llvm] 6e11676 - [SLP]Initial support for copyables in fmuladd intrinsic

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 29 04:42:51 PDT 2026


Author: Alexey Bataev
Date: 2026-07-29T07:42:45-04:00
New Revision: 6e116760ca4010be890b7fa39c93f2c902ab2a31

URL: https://github.com/llvm/llvm-project/commit/6e116760ca4010be890b7fa39c93f2c902ab2a31
DIFF: https://github.com/llvm/llvm-project/commit/6e116760ca4010be890b7fa39c93f2c902ab2a31.diff

LOG: [SLP]Initial support for copyables in fmuladd intrinsic

Adds llvm.fmuladd as a main operation for copyable elements. A
non-fmuladd lane V is modeled as fmuladd(0.0, -0.0, V), which equals
-0.0 + V == V for every V. Only the addend operand is supported for
now; multiplicand operands may be added later.

Reviewers: bababuck, hiraditya, RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/211245

Added: 
    

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
    llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-add-part.ll
    llvm/test/Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 1a26b6ae4e52d..3e4d3490a69aa 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -10720,9 +10720,8 @@ BoUpSLP::TreeEntry::EntryState BoUpSLP::getScalarsVectorizationState(
       if (isVectorIntrinsicWithScalarOpAtArg(ID, J, TTI))
         ScalarArgs[J] = CI->getArgOperand(J);
     for (Value *V : VL) {
-      // A copyable element stands in for the call via a substituted
-      // idempotent operand, so it is exempt from the checks below.
-      if (S.isCopyableElement(V))
+      // Skip copyables (idempotent stand-ins) and poisons.
+      if (isa<PoisonValue>(V) || S.isCopyableElement(V))
         continue;
       CallInst *CI2 = dyn_cast<CallInst>(V);
       Intrinsic::ID ID2 = CI2 ? getVectorIntrinsicIDForCall(CI2, TLI)
@@ -11326,10 +11325,12 @@ class InstructionsCompatibilityAnalysis {
   }
 
   /// Checks if \p I can be the main op for copyable analysis: a supported
-  /// binary operator or an integer min/max intrinsic, the only call with a
-  /// well-defined idempotent value (FP min/max lacks one because of NaNs).
+  /// binary operator, fmuladd, or an integer min/max intrinsic, the only
+  /// call with a well-defined idempotent value (FP min/max lacks one because of
+  /// NaNs).
   static bool isSupportedMainOp(Instruction *I) {
-    return isSupportedOpcode(I->getOpcode()) || isa<MinMaxIntrinsic>(I);
+    return isSupportedOpcode(I->getOpcode()) || isa<MinMaxIntrinsic>(I) ||
+           RecurrenceDescriptor::isFMulAddIntrinsic(I);
   }
 
   /// Identifies the best candidate value, which represents main opcode
@@ -11459,6 +11460,11 @@ class InstructionsCompatibilityAnalysis {
       return {V, V};
     if (!S.isCopyableElement(V))
       return convertTo(cast<Instruction>(V), S).second;
+    // fmuladd(0.0, -0.0, V) == V.
+    if (RecurrenceDescriptor::isFMulAddIntrinsic(MainOp)) {
+      Type *Ty = MainOp->getType();
+      return {ConstantFP::getZero(Ty), ConstantFP::getNegativeZero(Ty), V};
+    }
     assert(isSupportedMainOp(MainOp) && "Unsupported opcode");
     return {V, selectBestIdempotentValue()};
   }
@@ -11972,14 +11978,18 @@ class InstructionsCompatibilityAnalysis {
         VectorCost = TTI.getArithmeticInstrCost(MainOpcode, VecTy, Kind);
         break;
       default:
-        // Instruction::Call returns above before reaching this switch.
+        // Calls (min/max, fmuladd) return above before reaching this switch.
         llvm_unreachable("Unexpected instruction.");
       }
       if (VectorCost > ScalarCost)
         return OrigS;
       return S;
     }
-    assert(Operands.size() == 2 && "Unexpected number of operands!");
+    // fmuladd is the only 3-operand copyable; the value sits in the addend.
+    assert((Operands.size() == 2 ||
+            (Operands.size() == 3 &&
+             RecurrenceDescriptor::isFMulAddIntrinsic(MainOp))) &&
+           "Unexpected number of operands!");
     unsigned CopyableNum =
         count_if(VL, [&](Value *V) { return S.isCopyableElement(V); });
     if (CopyableNum < VL.size() / 2)
@@ -11995,7 +12005,7 @@ class InstructionsCompatibilityAnalysis {
       return OrigS;
     // Check profitability if number of copyables > VL.size() / 2.
     // 1. Reorder operands for better matching.
-    if (isCommutative(MainOp)) {
+    if (Operands.size() == 2 && isCommutative(MainOp)) {
       Value *BestFrontOp = nullptr;
       for (auto [OpL, OpR] : zip(Operands.front(), Operands.back())) {
         // Make instructions the first operands.
@@ -12028,8 +12038,10 @@ class InstructionsCompatibilityAnalysis {
         }
       }
     }
-    // 2. Check, if operands can be vectorized.
-    if (count_if(Operands.back(), IsaPred<Instruction>) > 1)
+    // 2. Check, if operands can be vectorized. Skip for fmuladd; its addend
+    // is checked below and may legitimately hold many instructions.
+    if (Operands.size() == 2 &&
+        count_if(Operands.back(), IsaPred<Instruction>) > 1)
       return OrigS;
     auto CheckOperand = [&](ArrayRef<Value *> Ops) {
       if (allConstant(Ops) || isSplat(Ops))
@@ -12064,7 +12076,9 @@ class InstructionsCompatibilityAnalysis {
           count_if(Ops, [&](Value *V) { return OpS.isCopyableElement(V); });
       return CopyableNum <= VL.size() / 2;
     };
-    if (!CheckOperand(Operands.front()))
+    // Check the addend for fmuladd, first operand otherwise.
+    if (!CheckOperand(Operands.size() == 2 ? Operands.front()
+                                           : Operands.back()))
       return OrigS;
 
     return S;
@@ -12077,10 +12091,12 @@ class InstructionsCompatibilityAnalysis {
     if (S.areInstructionsWithCopyableElements()) {
       MainOp = S.getMainOp();
       MainOpcode = S.getOpcode();
-      // Min/max is commutative, so this yields 2 args and never counts the
-      // trailing callee operand.
+      // Excludes the trailing callee operand (2 for min/max, 3 for fmuladd).
+      // getNumberOfPotentiallyCommutativeOps collapses fmuladd to 2 and must
+      // not be used here. Only the 2-operand case is commutative-normalized.
+      auto *CI = dyn_cast<CallInst>(MainOp);
       const unsigned NumMainOpOperands =
-          ::getNumberOfPotentiallyCommutativeOps(MainOp);
+          CI ? CI->arg_size() : MainOp->getNumOperands();
       const bool IsCommutative =
           isCommutative(MainOp) && NumMainOpOperands == 2;
       Operands.assign(NumMainOpOperands,

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-add-part.ll b/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-add-part.ll
index 3cdbff46e83c5..8feb518f4e823 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-add-part.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-add-part.ll
@@ -5,19 +5,33 @@
 declare double @llvm.fmuladd.f64(double, double, double)
 
 define void @test_main_opcode(ptr %dst, ptr %srcA, ptr %srcB, ptr %srcC) {
-; CHECK-LABEL: define void @test_main_opcode(
-; CHECK-SAME: ptr [[DST:%.*]], ptr [[SRCA:%.*]], ptr [[SRCB:%.*]], ptr [[SRCC:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[GEPC2:%.*]] = getelementptr double, ptr [[SRCC]], i32 2
-; CHECK-NEXT:    [[D2:%.*]] = getelementptr double, ptr [[DST]], i32 2
-; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[GEPC2]], align 8
-; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[SRCA]], align 8
-; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[SRCB]], align 8
-; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr [[SRCC]], align 8
-; CHECK-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP1]], <2 x double> [[TMP2]], <2 x double> [[TMP3]])
-; CHECK-NEXT:    store <2 x double> [[TMP4]], ptr [[DST]], align 8
-; CHECK-NEXT:    store <2 x double> [[TMP0]], ptr [[D2]], align 8
-; CHECK-NEXT:    ret void
+; ENABLED-LABEL: define void @test_main_opcode(
+; ENABLED-SAME: ptr [[DST:%.*]], ptr [[SRCA:%.*]], ptr [[SRCB:%.*]], ptr [[SRCC:%.*]]) {
+; ENABLED-NEXT:  [[ENTRY:.*:]]
+; ENABLED-NEXT:    [[GEPC2:%.*]] = getelementptr double, ptr [[SRCC]], i32 2
+; ENABLED-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[SRCA]], align 8
+; ENABLED-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[SRCB]], align 8
+; ENABLED-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[SRCC]], align 8
+; ENABLED-NEXT:    [[TMP3:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
+; ENABLED-NEXT:    [[D2:%.*]] = getelementptr double, ptr [[DST]], i32 2
+; ENABLED-NEXT:    [[TMP4:%.*]] = load <2 x double>, ptr [[GEPC2]], align 8
+; ENABLED-NEXT:    store <2 x double> [[TMP3]], ptr [[DST]], align 8
+; ENABLED-NEXT:    store <2 x double> [[TMP4]], ptr [[D2]], align 8
+; ENABLED-NEXT:    ret void
+;
+; DISABLED-LABEL: define void @test_main_opcode(
+; DISABLED-SAME: ptr [[DST:%.*]], ptr [[SRCA:%.*]], ptr [[SRCB:%.*]], ptr [[SRCC:%.*]]) {
+; DISABLED-NEXT:  [[ENTRY:.*:]]
+; DISABLED-NEXT:    [[GEPC2:%.*]] = getelementptr double, ptr [[SRCC]], i32 2
+; DISABLED-NEXT:    [[D2:%.*]] = getelementptr double, ptr [[DST]], i32 2
+; DISABLED-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[GEPC2]], align 8
+; DISABLED-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[SRCA]], align 8
+; DISABLED-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[SRCB]], align 8
+; DISABLED-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr [[SRCC]], align 8
+; DISABLED-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP1]], <2 x double> [[TMP2]], <2 x double> [[TMP3]])
+; DISABLED-NEXT:    store <2 x double> [[TMP4]], ptr [[DST]], align 8
+; DISABLED-NEXT:    store <2 x double> [[TMP0]], ptr [[D2]], align 8
+; DISABLED-NEXT:    ret void
 ;
 entry:
   %a0 = load double, ptr %srcA, align 8
@@ -46,36 +60,20 @@ entry:
 }
 
 define void @test_main_opcode_fadd_copyable(ptr %dst, ptr %srcA, ptr %srcB, ptr %srcC, double %p, double %q) {
-; ENABLED-LABEL: define void @test_main_opcode_fadd_copyable(
-; ENABLED-SAME: ptr [[DST:%.*]], ptr [[SRCA:%.*]], ptr [[SRCB:%.*]], ptr [[SRCC:%.*]], double [[P:%.*]], double [[Q:%.*]]) {
-; ENABLED-NEXT:  [[ENTRY:.*:]]
-; ENABLED-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[SRCA]], align 8
-; ENABLED-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[SRCB]], align 8
-; ENABLED-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[SRCC]], align 8
-; ENABLED-NEXT:    [[TMP3:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
-; ENABLED-NEXT:    store <2 x double> [[TMP3]], ptr [[DST]], align 8
-; ENABLED-NEXT:    [[D2:%.*]] = getelementptr double, ptr [[DST]], i32 2
-; ENABLED-NEXT:    [[TMP4:%.*]] = insertelement <2 x double> <double poison, double -0.000000e+00>, double [[P]], i64 0
-; ENABLED-NEXT:    [[TMP5:%.*]] = insertelement <2 x double> poison, double [[Q]], i64 0
-; ENABLED-NEXT:    [[TMP6:%.*]] = shufflevector <2 x double> [[TMP5]], <2 x double> poison, <2 x i32> zeroinitializer
-; ENABLED-NEXT:    [[TMP7:%.*]] = fadd <2 x double> [[TMP4]], [[TMP6]]
-; ENABLED-NEXT:    store <2 x double> [[TMP7]], ptr [[D2]], align 8
-; ENABLED-NEXT:    ret void
-;
-; DISABLED-LABEL: define void @test_main_opcode_fadd_copyable(
-; DISABLED-SAME: ptr [[DST:%.*]], ptr [[SRCA:%.*]], ptr [[SRCB:%.*]], ptr [[SRCC:%.*]], double [[P:%.*]], double [[Q:%.*]]) {
-; DISABLED-NEXT:  [[ENTRY:.*:]]
-; DISABLED-NEXT:    [[FADD:%.*]] = fadd double [[P]], [[Q]]
-; DISABLED-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[SRCA]], align 8
-; DISABLED-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[SRCB]], align 8
-; DISABLED-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[SRCC]], align 8
-; DISABLED-NEXT:    [[TMP3:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
-; DISABLED-NEXT:    store <2 x double> [[TMP3]], ptr [[DST]], align 8
-; DISABLED-NEXT:    [[D2:%.*]] = getelementptr double, ptr [[DST]], i32 2
-; DISABLED-NEXT:    store double [[FADD]], ptr [[D2]], align 8
-; DISABLED-NEXT:    [[D3:%.*]] = getelementptr double, ptr [[DST]], i32 3
-; DISABLED-NEXT:    store double [[Q]], ptr [[D3]], align 8
-; DISABLED-NEXT:    ret void
+; CHECK-LABEL: define void @test_main_opcode_fadd_copyable(
+; CHECK-SAME: ptr [[DST:%.*]], ptr [[SRCA:%.*]], ptr [[SRCB:%.*]], ptr [[SRCC:%.*]], double [[P:%.*]], double [[Q:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[FADD:%.*]] = fadd double [[P]], [[Q]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[SRCA]], align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[SRCB]], align 8
+; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[SRCC]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP2]])
+; CHECK-NEXT:    store <2 x double> [[TMP3]], ptr [[DST]], align 8
+; CHECK-NEXT:    [[D2:%.*]] = getelementptr double, ptr [[DST]], i32 2
+; CHECK-NEXT:    store double [[FADD]], ptr [[D2]], align 8
+; CHECK-NEXT:    [[D3:%.*]] = getelementptr double, ptr [[DST]], i32 3
+; CHECK-NEXT:    store double [[Q]], ptr [[D3]], align 8
+; CHECK-NEXT:    ret void
 ;
 entry:
   %a0 = load double, ptr %srcA, align 8
@@ -101,14 +99,25 @@ entry:
 }
 
 define void @test_two_lanes(ptr %dst, double %a0, double %b0, double %c0, double %x) {
-; CHECK-LABEL: define void @test_two_lanes(
-; CHECK-SAME: ptr [[DST:%.*]], double [[A0:%.*]], double [[B0:%.*]], double [[C0:%.*]], double [[X:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[FMA0:%.*]] = call double @llvm.fmuladd.f64(double [[A0]], double [[B0]], double [[C0]])
-; CHECK-NEXT:    store double [[FMA0]], ptr [[DST]], align 8
-; CHECK-NEXT:    [[D1:%.*]] = getelementptr double, ptr [[DST]], i32 1
-; CHECK-NEXT:    store double [[X]], ptr [[D1]], align 8
-; CHECK-NEXT:    ret void
+; ENABLED-LABEL: define void @test_two_lanes(
+; ENABLED-SAME: ptr [[DST:%.*]], double [[A0:%.*]], double [[B0:%.*]], double [[C0:%.*]], double [[X:%.*]]) {
+; ENABLED-NEXT:  [[ENTRY:.*:]]
+; ENABLED-NEXT:    [[TMP0:%.*]] = insertelement <2 x double> <double poison, double -0.000000e+00>, double [[A0]], i64 0
+; ENABLED-NEXT:    [[TMP1:%.*]] = insertelement <2 x double> <double poison, double 0.000000e+00>, double [[B0]], i64 0
+; ENABLED-NEXT:    [[TMP2:%.*]] = insertelement <2 x double> poison, double [[C0]], i64 0
+; ENABLED-NEXT:    [[TMP3:%.*]] = insertelement <2 x double> [[TMP2]], double [[X]], i64 1
+; ENABLED-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP0]], <2 x double> [[TMP1]], <2 x double> [[TMP3]])
+; ENABLED-NEXT:    store <2 x double> [[TMP4]], ptr [[DST]], align 8
+; ENABLED-NEXT:    ret void
+;
+; DISABLED-LABEL: define void @test_two_lanes(
+; DISABLED-SAME: ptr [[DST:%.*]], double [[A0:%.*]], double [[B0:%.*]], double [[C0:%.*]], double [[X:%.*]]) {
+; DISABLED-NEXT:  [[ENTRY:.*:]]
+; DISABLED-NEXT:    [[FMA0:%.*]] = call double @llvm.fmuladd.f64(double [[A0]], double [[B0]], double [[C0]])
+; DISABLED-NEXT:    store double [[FMA0]], ptr [[DST]], align 8
+; DISABLED-NEXT:    [[D1:%.*]] = getelementptr double, ptr [[DST]], i32 1
+; DISABLED-NEXT:    store double [[X]], ptr [[D1]], align 8
+; DISABLED-NEXT:    ret void
 ;
 entry:
   %fma0 = call double @llvm.fmuladd.f64(double %a0, double %b0, double %c0)

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll b/llvm/test/Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll
index 060a662659f65..a75b9886e680f 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll
@@ -6,11 +6,8 @@ define <16 x half> @test(i32 %0, float %1, i32 %2) {
 ; CHECK-SAME: i32 [[TMP0:%.*]], float [[TMP1:%.*]], i32 [[TMP2:%.*]]) {
 ; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <16 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float poison, float 0.000000e+00, float 0.000000e+00>, float [[TMP1]], i64 13
 ; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <16 x float> [[TMP4]] to <16 x i32>
-; CHECK-NEXT:    [[TMP6:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> zeroinitializer, <2 x float> zeroinitializer, <2 x float> zeroinitializer)
 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp ugt i32 [[TMP2]], 0
 ; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[TMP0]], [[TMP0]]
-; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x float> [[TMP6]], i64 0
-; CHECK-NEXT:    [[TMP10:%.*]] = fcmp ogt float [[TMP9]], 0.000000e+00
 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[TMP0]], 0
 ; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i32 [[TMP0]], 0
 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <16 x i32> [[TMP5]], i64 10
@@ -27,6 +24,7 @@ define <16 x half> @test(i32 %0, float %1, i32 %2) {
 ; CHECK-NEXT:    [[TMP24:%.*]] = icmp eq i32 [[TMP0]], [[TMP0]]
 ; CHECK-NEXT:    [[TMP23:%.*]] = bitcast float 0.000000e+00 to i32
 ; CHECK-NEXT:    [[TMP32:%.*]] = icmp eq i32 [[TMP23]], 0
+; CHECK-NEXT:    [[TMP25:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> zeroinitializer, <2 x float> zeroinitializer, <2 x float> zeroinitializer)
 ; CHECK-NEXT:    [[TMP27:%.*]] = icmp ult <16 x i32> [[TMP5]], zeroinitializer
 ; CHECK-NEXT:    [[TMP28:%.*]] = select <16 x i1> [[TMP27]], <16 x i32> zeroinitializer, <16 x i32> zeroinitializer
 ; CHECK-NEXT:    [[TMP29:%.*]] = sitofp <16 x i32> [[TMP28]] to <16 x float>
@@ -39,13 +37,15 @@ define <16 x half> @test(i32 %0, float %1, i32 %2) {
 ; CHECK-NEXT:    [[TMP36:%.*]] = bitcast <16 x float> [[TMP35]] to <16 x i32>
 ; CHECK-NEXT:    [[TMP37:%.*]] = and <16 x i32> [[TMP36]], zeroinitializer
 ; CHECK-NEXT:    [[TMP38:%.*]] = bitcast <16 x i32> [[TMP37]] to <16 x float>
-; CHECK-NEXT:    [[TMP53:%.*]] = shufflevector <2 x float> [[TMP6]], <2 x float> poison, <16 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
-; CHECK-NEXT:    [[TMP39:%.*]] = shufflevector <16 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float poison, float poison>, <16 x float> [[TMP53]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 16, i32 17>
+; CHECK-NEXT:    [[TMP57:%.*]] = shufflevector <2 x float> [[TMP25]], <2 x float> poison, <16 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[TMP39:%.*]] = shufflevector <16 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float poison, float poison>, <16 x float> [[TMP57]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 16, i32 17>
 ; CHECK-NEXT:    [[TMP40:%.*]] = call <16 x float> @llvm.fmuladd.v16f32(<16 x float> zeroinitializer, <16 x float> [[TMP38]], <16 x float> [[TMP39]])
 ; CHECK-NEXT:    [[TMP43:%.*]] = extractelement <16 x float> [[TMP29]], i64 0
 ; CHECK-NEXT:    [[TMP44:%.*]] = fcmp olt float [[TMP43]], 0.000000e+00
 ; CHECK-NEXT:    [[TMP45:%.*]] = extractelement <16 x float> [[TMP29]], i64 14
 ; CHECK-NEXT:    [[TMP49:%.*]] = fcmp ogt float [[TMP45]], 0.000000e+00
+; CHECK-NEXT:    [[TMP53:%.*]] = extractelement <2 x float> [[TMP25]], i64 0
+; CHECK-NEXT:    [[TMP56:%.*]] = fcmp ogt float [[TMP53]], 0.000000e+00
 ; CHECK-NEXT:    [[TMP46:%.*]] = fcmp olt float [[TMP45]], 0.000000e+00
 ; CHECK-NEXT:    [[TMP47:%.*]] = extractelement <16 x float> [[TMP29]], i64 13
 ; CHECK-NEXT:    [[TMP50:%.*]] = fcmp ogt float [[TMP47]], 0.000000e+00


        


More information about the llvm-commits mailing list