llvm.org GIT mirror llvm / ae08dcb
[IR] allow fast-math-flags on select of FP values This is a minimal start to correcting a problem most directly discussed in PR38086: https://bugs.llvm.org/show_bug.cgi?id=38086 We have been hacking around a limitation for FP select patterns by using the fast-math-flags on the condition of the select rather than the select itself. This patch just allows FMF to appear with the 'select' opcode. No changes are needed to "FPMathOperator" because it already includes select-of-FP because that definition is based on the (return) value type. Once we have this ability, we can start correcting and adding IR transforms to use the FMF on a 'select' instruction. The instcombine and vectorizer test diffs only show that the IRBuilder change is behaving as expected by applying an FMF guard value to 'select'. For reference: rL241901 - allowed FMF with fcmp rL255555 - allowed FMF with FP calls Differential Revision: https://reviews.llvm.org/D61917 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361401 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 1 year, 6 months ago
11 changed file(s) with 92 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
99309930
99319931 ::
99329932
9933 = select selty , , ; yields ty
9933 = select [fast-math flags] selty , , ; yields ty
99349934
99359935 selty is either i1 or {}
99369936
99469946 The '``select``' instruction requires an 'i1' value or a vector of 'i1'
99479947 values indicating the condition, and two values of the same :ref:`first
99489948 class ` type.
9949
9950 #. The optional ``fast-math flags`` marker indicates that the select has one or more
9951 :ref:`fast-math flags `. These are optimization hints to enable
9952 otherwise unsafe floating-point optimizations. Fast-math flags are only valid
9953 for selects that return a floating-point scalar or vector type.
99499954
99509955 Semantics:
99519956 """"""""""
20662066 MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable);
20672067 Sel = addBranchMetadata(Sel, Prof, Unpred);
20682068 }
2069 if (isa(Sel))
2070 Sel = cast(setFPAttrs(Sel, nullptr /* MDNode* */, FMF));
20692071 return Insert(Sel, Name);
20702072 }
20712073
57005700 case lltok::kw_inttoptr:
57015701 case lltok::kw_ptrtoint: return ParseCast(Inst, PFS, KeywordVal);
57025702 // Other.
5703 case lltok::kw_select: return ParseSelect(Inst, PFS);
5703 case lltok::kw_select: {
5704 FastMathFlags FMF = EatFastMathFlagsIfPresent();
5705 int Res = ParseSelect(Inst, PFS);
5706 if (Res != 0)
5707 return Res;
5708 if (FMF.any()) {
5709 if (!Inst->getType()->isFPOrFPVectorTy())
5710 return Error(Loc, "fast-math-flags specified for select without "
5711 "floating-point scalar or vector return type");
5712 Inst->setFastMathFlags(FMF);
5713 }
5714 return 0;
5715 }
57045716 case lltok::kw_va_arg: return ParseVA_Arg(Inst, PFS);
57055717 case lltok::kw_extractelement: return ParseExtractElement(Inst, PFS);
57065718 case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS);
38343834
38353835 I = SelectInst::Create(Cond, TrueVal, FalseVal);
38363836 InstructionList.push_back(I);
3837 if (OpNum < Record.size() && isa(I)) {
3838 FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]);
3839 if (FMF.any())
3840 I->setFastMathFlags(FMF);
3841 }
38373842 break;
38383843 }
38393844
26352635 Vals.append(IVI->idx_begin(), IVI->idx_end());
26362636 break;
26372637 }
2638 case Instruction::Select:
2638 case Instruction::Select: {
26392639 Code = bitc::FUNC_CODE_INST_VSELECT;
26402640 pushValueAndType(I.getOperand(1), InstID, Vals);
26412641 pushValue(I.getOperand(2), InstID, Vals);
26422642 pushValueAndType(I.getOperand(0), InstID, Vals);
2643 uint64_t Flags = getOptimizationFlags(&I);
2644 if (Flags != 0)
2645 Vals.push_back(Flags);
26432646 break;
2647 }
26442648 case Instruction::ExtractElement:
26452649 Code = bitc::FUNC_CODE_INST_EXTRACTELT;
26462650 pushValueAndType(I.getOperand(0), InstID, Vals);
814814 ret void
815815 }
816816
817 define void @fastmathflags_select(i1 %cond, float %op1, float %op2) {
818 %f.nnan = select nnan i1 %cond, float %op1, float %op2
819 ; CHECK: %f.nnan = select nnan i1 %cond, float %op1, float %op2
820 %f.ninf = select ninf i1 %cond, float %op1, float %op2
821 ; CHECK: %f.ninf = select ninf i1 %cond, float %op1, float %op2
822 %f.nsz = select nsz i1 %cond, float %op1, float %op2
823 ; CHECK: %f.nsz = select nsz i1 %cond, float %op1, float %op2
824 %f.arcp = select arcp i1 %cond, float %op1, float %op2
825 ; CHECK: %f.arcp = select arcp i1 %cond, float %op1, float %op2
826 %f.contract = select contract i1 %cond, float %op1, float %op2
827 ; CHECK: %f.contract = select contract i1 %cond, float %op1, float %op2
828 %f.afn = select afn i1 %cond, float %op1, float %op2
829 ; CHECK: %f.afn = select afn i1 %cond, float %op1, float %op2
830 %f.reassoc = select reassoc i1 %cond, float %op1, float %op2
831 ; CHECK: %f.reassoc = select reassoc i1 %cond, float %op1, float %op2
832 %f.fast = select fast i1 %cond, float %op1, float %op2
833 ; CHECK: %f.fast = select fast i1 %cond, float %op1, float %op2
834 ret void
835 }
836
837 define void @fastmathflags_vector_select(<2 x i1> %cond, <2 x double> %op1, <2 x double> %op2) {
838 %f.nnan.nsz = select nnan nsz <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
839 ; CHECK: %f.nnan.nsz = select nnan nsz <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
840 %f.fast = select fast <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
841 ; CHECK: %f.fast = select fast <2 x i1> %cond, <2 x double> %op1, <2 x double> %op2
842 ret void
843 }
844
817845 ; Check various fast math flags and floating-point types on calls.
818846
819847 declare float @fmf1()
276276 ; CHECK-NEXT: entry:
277277 ; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <2 x double> [[VEC:%.*]], <2 x double> undef, <2 x i32>
278278 ; CHECK-NEXT: [[RDX_MINMAX_CMP:%.*]] = fcmp fast ogt <2 x double> [[VEC]], [[RDX_SHUF]]
279 ; CHECK-NEXT: [[RDX_MINMAX_SELECT:%.*]] = select <2 x i1> [[RDX_MINMAX_CMP]], <2 x double> [[VEC]], <2 x double> [[RDX_SHUF]]
279 ; CHECK-NEXT: [[RDX_MINMAX_SELECT:%.*]] = select fast <2 x i1> [[RDX_MINMAX_CMP]], <2 x double> [[VEC]], <2 x double> [[RDX_SHUF]]
280280 ; CHECK-NEXT: [[TMP0:%.*]] = extractelement <2 x double> [[RDX_MINMAX_SELECT]], i32 0
281281 ; CHECK-NEXT: ret double [[TMP0]]
282282 ;
290290 ; CHECK-NEXT: entry:
291291 ; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <2 x double> [[VEC:%.*]], <2 x double> undef, <2 x i32>
292292 ; CHECK-NEXT: [[RDX_MINMAX_CMP:%.*]] = fcmp fast olt <2 x double> [[VEC]], [[RDX_SHUF]]
293 ; CHECK-NEXT: [[RDX_MINMAX_SELECT:%.*]] = select <2 x i1> [[RDX_MINMAX_CMP]], <2 x double> [[VEC]], <2 x double> [[RDX_SHUF]]
293 ; CHECK-NEXT: [[RDX_MINMAX_SELECT:%.*]] = select fast <2 x i1> [[RDX_MINMAX_CMP]], <2 x double> [[VEC]], <2 x double> [[RDX_SHUF]]
294294 ; CHECK-NEXT: [[TMP0:%.*]] = extractelement <2 x double> [[RDX_MINMAX_SELECT]], i32 0
295295 ; CHECK-NEXT: ret double [[TMP0]]
296296 ;
819819 define float @max1(float %a, float %b) {
820820 ; CHECK-LABEL: @max1(
821821 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp fast ogt float [[A:%.*]], [[B:%.*]]
822 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], float [[A]], float [[B]]
822 ; CHECK-NEXT: [[TMP2:%.*]] = select fast i1 [[TMP1]], float [[A]], float [[B]]
823823 ; CHECK-NEXT: ret float [[TMP2]]
824824 ;
825825 %c = fpext float %a to double
832832 define float @max2(float %a, float %b) {
833833 ; CHECK-LABEL: @max2(
834834 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp nnan nsz ogt float [[A:%.*]], [[B:%.*]]
835 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], float [[A]], float [[B]]
835 ; CHECK-NEXT: [[TMP2:%.*]] = select nnan nsz i1 [[TMP1]], float [[A]], float [[B]]
836836 ; CHECK-NEXT: ret float [[TMP2]]
837837 ;
838838 %c = call nnan float @fmaxf(float %a, float %b)
843843 define double @max3(double %a, double %b) {
844844 ; CHECK-LABEL: @max3(
845845 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp fast ogt double [[A:%.*]], [[B:%.*]]
846 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], double [[A]], double [[B]]
846 ; CHECK-NEXT: [[TMP2:%.*]] = select fast i1 [[TMP1]], double [[A]], double [[B]]
847847 ; CHECK-NEXT: ret double [[TMP2]]
848848 ;
849849 %c = call fast double @fmax(double %a, double %b)
853853 define fp128 @max4(fp128 %a, fp128 %b) {
854854 ; CHECK-LABEL: @max4(
855855 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp nnan nsz ogt fp128 [[A:%.*]], [[B:%.*]]
856 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], fp128 [[A]], fp128 [[B]]
856 ; CHECK-NEXT: [[TMP2:%.*]] = select nnan nsz i1 [[TMP1]], fp128 [[A]], fp128 [[B]]
857857 ; CHECK-NEXT: ret fp128 [[TMP2]]
858858 ;
859859 %c = call nnan fp128 @fmaxl(fp128 %a, fp128 %b)
864864 define float @min1(float %a, float %b) {
865865 ; CHECK-LABEL: @min1(
866866 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp nnan nsz olt float [[A:%.*]], [[B:%.*]]
867 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], float [[A]], float [[B]]
867 ; CHECK-NEXT: [[TMP2:%.*]] = select nnan nsz i1 [[TMP1]], float [[A]], float [[B]]
868868 ; CHECK-NEXT: ret float [[TMP2]]
869869 ;
870870 %c = fpext float %a to double
877877 define float @min2(float %a, float %b) {
878878 ; CHECK-LABEL: @min2(
879879 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp fast olt float [[A:%.*]], [[B:%.*]]
880 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], float [[A]], float [[B]]
880 ; CHECK-NEXT: [[TMP2:%.*]] = select fast i1 [[TMP1]], float [[A]], float [[B]]
881881 ; CHECK-NEXT: ret float [[TMP2]]
882882 ;
883883 %c = call fast float @fminf(float %a, float %b)
887887 define double @min3(double %a, double %b) {
888888 ; CHECK-LABEL: @min3(
889889 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp nnan nsz olt double [[A:%.*]], [[B:%.*]]
890 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], double [[A]], double [[B]]
890 ; CHECK-NEXT: [[TMP2:%.*]] = select nnan nsz i1 [[TMP1]], double [[A]], double [[B]]
891891 ; CHECK-NEXT: ret double [[TMP2]]
892892 ;
893893 %c = call nnan double @fmin(double %a, double %b)
897897 define fp128 @min4(fp128 %a, fp128 %b) {
898898 ; CHECK-LABEL: @min4(
899899 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp fast olt fp128 [[A:%.*]], [[B:%.*]]
900 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], fp128 [[A]], fp128 [[B]]
900 ; CHECK-NEXT: [[TMP2:%.*]] = select fast i1 [[TMP1]], fp128 [[A]], fp128 [[B]]
901901 ; CHECK-NEXT: ret fp128 [[TMP2]]
902902 ;
903903 %c = call fast fp128 @fminl(fp128 %a, fp128 %b)
3535 ; CHECK-NEXT: [[SQRT:%.*]] = call afn double @sqrt(double [[X:%.*]])
3636 ; CHECK-NEXT: [[ABS:%.*]] = call afn double @llvm.fabs.f64(double [[SQRT]])
3737 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp afn oeq double [[X]], 0xFFF0000000000000
38 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
38 ; CHECK-NEXT: [[TMP1:%.*]] = select afn i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
3939 ; CHECK-NEXT: ret double [[TMP1]]
4040 ;
4141 %pow = call afn double @pow(double %x, double 5.0e-01)
4747 ; CHECK-NEXT: [[SQRT:%.*]] = call afn <2 x double> @llvm.sqrt.v2f64(<2 x double> [[X:%.*]])
4848 ; CHECK-NEXT: [[ABS:%.*]] = call afn <2 x double> @llvm.fabs.v2f64(<2 x double> [[SQRT]])
4949 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp afn oeq <2 x double> [[X]],
50 ; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> [[ISINF]], <2 x double> , <2 x double> [[ABS]]
50 ; CHECK-NEXT: [[TMP1:%.*]] = select afn <2 x i1> [[ISINF]], <2 x double> , <2 x double> [[ABS]]
5151 ; CHECK-NEXT: ret <2 x double> [[TMP1]]
5252 ;
5353 %pow = call afn <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> )
9191 ; CHECK-LABEL: @pow_libcall_half_nsz(
9292 ; CHECK-NEXT: [[SQRT:%.*]] = call nsz double @sqrt(double [[X:%.*]])
9393 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp nsz oeq double [[X]], 0xFFF0000000000000
94 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[SQRT]]
94 ; CHECK-NEXT: [[TMP1:%.*]] = select nsz i1 [[ISINF]], double 0x7FF0000000000000, double [[SQRT]]
9595 ; CHECK-NEXT: ret double [[TMP1]]
9696 ;
9797 %pow = call nsz double @pow(double %x, double 5.0e-01)
102102 ; CHECK-LABEL: @pow_intrinsic_half_nsz(
103103 ; CHECK-NEXT: [[SQRT:%.*]] = call nsz double @llvm.sqrt.f64(double [[X:%.*]])
104104 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp nsz oeq double [[X]], 0xFFF0000000000000
105 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[SQRT]]
105 ; CHECK-NEXT: [[TMP1:%.*]] = select nsz i1 [[ISINF]], double 0x7FF0000000000000, double [[SQRT]]
106106 ; CHECK-NEXT: ret double [[TMP1]]
107107 ;
108108 %pow = call nsz double @llvm.pow.f64(double %x, double 5.0e-01)
7373 ; CHECK: middle.block:
7474 ; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x float> [[TMP6]], <4 x float> undef, <4 x i32>
7575 ; CHECK-NEXT: [[RDX_MINMAX_CMP:%.*]] = fcmp fast olt <4 x float> [[TMP6]], [[RDX_SHUF]]
76 ; CHECK-NEXT: [[RDX_MINMAX_SELECT:%.*]] = select <4 x i1> [[RDX_MINMAX_CMP]], <4 x float> [[TMP6]], <4 x float> [[RDX_SHUF]]
76 ; CHECK-NEXT: [[RDX_MINMAX_SELECT:%.*]] = select fast <4 x i1> [[RDX_MINMAX_CMP]], <4 x float> [[TMP6]], <4 x float> [[RDX_SHUF]]
7777 ; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <4 x float> [[RDX_MINMAX_SELECT]], <4 x float> undef, <4 x i32>
7878 ; CHECK-NEXT: [[RDX_MINMAX_CMP2:%.*]] = fcmp fast olt <4 x float> [[RDX_MINMAX_SELECT]], [[RDX_SHUF1]]
79 ; CHECK-NEXT: [[RDX_MINMAX_SELECT3:%.*]] = select <4 x i1> [[RDX_MINMAX_CMP2]], <4 x float> [[RDX_MINMAX_SELECT]], <4 x float> [[RDX_SHUF1]]
79 ; CHECK-NEXT: [[RDX_MINMAX_SELECT3:%.*]] = select fast <4 x i1> [[RDX_MINMAX_CMP2]], <4 x float> [[RDX_MINMAX_SELECT]], <4 x float> [[RDX_SHUF1]]
8080 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x float> [[RDX_MINMAX_SELECT3]], i32 0
8181 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 65536, 65536
8282 ; CHECK-NEXT: br i1 [[CMP_N]], label [[OUT:%.*]], label [[SCALAR_PH]]
415415 ; CHECK: select <2 x i1>
416416 ; CHECK: middle.block
417417 ; CHECK: fcmp fast ogt <2 x float>
418 ; CHECK: select <2 x i1>
418 ; CHECK: select fast <2 x i1>
419419
420420 define float @max_red_float(float %max) #0 {
421421 entry:
441441 ; CHECK: select <2 x i1>
442442 ; CHECK: middle.block
443443 ; CHECK: fcmp fast ogt <2 x float>
444 ; CHECK: select <2 x i1>
444 ; CHECK: select fast <2 x i1>
445445
446446 define float @max_red_float_ge(float %max) #0 {
447447 entry:
467467 ; CHECK: select <2 x i1>
468468 ; CHECK: middle.block
469469 ; CHECK: fcmp fast ogt <2 x float>
470 ; CHECK: select <2 x i1>
470 ; CHECK: select fast <2 x i1>
471471
472472 define float @inverted_max_red_float(float %max) #0 {
473473 entry:
493493 ; CHECK: select <2 x i1>
494494 ; CHECK: middle.block
495495 ; CHECK: fcmp fast ogt <2 x float>
496 ; CHECK: select <2 x i1>
496 ; CHECK: select fast <2 x i1>
497497
498498 define float @inverted_max_red_float_le(float %max) #0 {
499499 entry:
519519 ; CHECK: select <2 x i1>
520520 ; CHECK: middle.block
521521 ; CHECK: fcmp fast ogt <2 x float>
522 ; CHECK: select <2 x i1>
522 ; CHECK: select fast <2 x i1>
523523
524524 define float @unordered_max_red_float(float %max) #0 {
525525 entry:
545545 ; CHECK: select <2 x i1>
546546 ; CHECK: middle.block
547547 ; CHECK: fcmp fast ogt <2 x float>
548 ; CHECK: select <2 x i1>
548 ; CHECK: select fast <2 x i1>
549549
550550 define float @unordered_max_red_float_ge(float %max) #0 {
551551 entry:
571571 ; CHECK: select <2 x i1>
572572 ; CHECK: middle.block
573573 ; CHECK: fcmp fast ogt <2 x float>
574 ; CHECK: select <2 x i1>
574 ; CHECK: select fast <2 x i1>
575575
576576 define float @inverted_unordered_max_red_float(float %max) #0 {
577577 entry:
597597 ; CHECK: select <2 x i1>
598598 ; CHECK: middle.block
599599 ; CHECK: fcmp fast ogt <2 x float>
600 ; CHECK: select <2 x i1>
600 ; CHECK: select fast <2 x i1>
601601
602602 define float @inverted_unordered_max_red_float_le(float %max) #0 {
603603 entry:
626626 ; CHECK: select <2 x i1>
627627 ; CHECK: middle.block
628628 ; CHECK: fcmp fast olt <2 x float>
629 ; CHECK: select <2 x i1>
629 ; CHECK: select fast <2 x i1>
630630
631631 define float @min_red_float(float %min) #0 {
632632 entry:
652652 ; CHECK: select <2 x i1>
653653 ; CHECK: middle.block
654654 ; CHECK: fcmp fast olt <2 x float>
655 ; CHECK: select <2 x i1>
655 ; CHECK: select fast <2 x i1>
656656
657657 define float @min_red_float_le(float %min) #0 {
658658 entry:
678678 ; CHECK: select <2 x i1>
679679 ; CHECK: middle.block
680680 ; CHECK: fcmp fast olt <2 x float>
681 ; CHECK: select <2 x i1>
681 ; CHECK: select fast <2 x i1>
682682
683683 define float @inverted_min_red_float(float %min) #0 {
684684 entry:
704704 ; CHECK: select <2 x i1>
705705 ; CHECK: middle.block
706706 ; CHECK: fcmp fast olt <2 x float>
707 ; CHECK: select <2 x i1>
707 ; CHECK: select fast <2 x i1>
708708
709709 define float @inverted_min_red_float_ge(float %min) #0 {
710710 entry:
730730 ; CHECK: select <2 x i1>
731731 ; CHECK: middle.block
732732 ; CHECK: fcmp fast olt <2 x float>
733 ; CHECK: select <2 x i1>
733 ; CHECK: select fast <2 x i1>
734734
735735 define float @unordered_min_red_float(float %min) #0 {
736736 entry:
756756 ; CHECK: select <2 x i1>
757757 ; CHECK: middle.block
758758 ; CHECK: fcmp fast olt <2 x float>
759 ; CHECK: select <2 x i1>
759 ; CHECK: select fast <2 x i1>
760760
761761 define float @unordered_min_red_float_le(float %min) #0 {
762762 entry:
782782 ; CHECK: select <2 x i1>
783783 ; CHECK: middle.block
784784 ; CHECK: fcmp fast olt <2 x float>
785 ; CHECK: select <2 x i1>
785 ; CHECK: select fast <2 x i1>
786786
787787 define float @inverted_unordered_min_red_float(float %min) #0 {
788788 entry:
808808 ; CHECK: select <2 x i1>
809809 ; CHECK: middle.block
810810 ; CHECK: fcmp fast olt <2 x float>
811 ; CHECK: select <2 x i1>
811 ; CHECK: select fast <2 x i1>
812812
813813 define float @inverted_unordered_min_red_float_ge(float %min) #0 {
814814 entry:
835835 ; CHECK: select <2 x i1>
836836 ; CHECK: middle.block
837837 ; CHECK: fcmp fast olt <2 x double>
838 ; CHECK: select <2 x i1>
838 ; CHECK: select fast <2 x i1>
839839
840840 define double @min_red_double(double %min) #0 {
841841 entry: