1 ; RUN: opt -S -instcombine < %s | FileCheck %s 2 3 ; CHECK-LABEL: @t1 4 ; CHECK-NEXT: fcmp oge float %a, 5.000000e+00 5 ; CHECK-NEXT: select i1 %.inv, float 5.000000e+00, float %a 6 ; CHECK-NEXT: fpext float %1 to double 7 define double @t1(float %a) { 8 ; This is the canonical form for a type-changing min/max. 9 %1 = fcmp ult float %a, 5.0 10 %2 = select i1 %1, float %a, float 5.0 11 %3 = fpext float %2 to double 12 ret double %3 13 } 14 15 ; CHECK-LABEL: @t2 16 ; CHECK-NEXT: fcmp oge float %a, 5.000000e+00 17 ; CHECK-NEXT: select i1 %.inv, float 5.000000e+00, float %a 18 ; CHECK-NEXT: fpext float %1 to double 19 define double @t2(float %a) { 20 ; Check this is converted into canonical form, as above. 21 %1 = fcmp ult float %a, 5.0 22 %2 = fpext float %a to double 23 %3 = select i1 %1, double %2, double 5.0 24 ret double %3 25 } 26 27 ; CHECK-LABEL: @t4 28 ; CHECK-NEXT: fcmp oge double %a, 5.000000e+00 29 ; CHECK-NEXT: select i1 %.inv, double 5.000000e+00, double %a 30 ; CHECK-NEXT: fptrunc double %1 to float 31 define float @t4(double %a) { 32 ; Same again, with trunc. 33 %1 = fcmp ult double %a, 5.0 34 %2 = fptrunc double %a to float 35 %3 = select i1 %1, float %2, float 5.0 36 ret float %3 37 } 38 39 ; CHECK-LABEL: @t5 40 ; CHECK-NEXT: fcmp ult float %a, 5.000000e+00 41 ; CHECK-NEXT: fpext float %a to double 42 ; CHECK-NEXT: select i1 %1, double %2, double 5.001 43 define double @t5(float %a) { 44 ; different values, should not be converted. 45 %1 = fcmp ult float %a, 5.0 46 %2 = fpext float %a to double 47 %3 = select i1 %1, double %2, double 5.001 48 ret double %3 49 } 50 51 ; CHECK-LABEL: @t6 52 ; CHECK-NEXT: fcmp ult float %a, -0.0 53 ; CHECK-NEXT: fpext float %a to double 54 ; CHECK-NEXT: select i1 %1, double %2, double 0.0 55 define double @t6(float %a) { 56 ; Signed zero, should not be converted 57 %1 = fcmp ult float %a, -0.0 58 %2 = fpext float %a to double 59 %3 = select i1 %1, double %2, double 0.0 60 ret double %3 61 } 62 63 ; CHECK-LABEL: @t7 64 ; CHECK-NEXT: fcmp ult float %a, 0.0 65 ; CHECK-NEXT: fpext float %a to double 66 ; CHECK-NEXT: select i1 %1, double %2, double -0.0 67 define double @t7(float %a) { 68 ; Signed zero, should not be converted 69 %1 = fcmp ult float %a, 0.0 70 %2 = fpext float %a to double 71 %3 = select i1 %1, double %2, double -0.0 72 ret double %3 73 } 74 75 ; CHECK-LABEL: @t8 76 ; CHECK-NEXT: fcmp oge float %a, 5.000000e+00 77 ; CHECK-NEXT: select i1 %.inv, float 5.000000e+00, float %a 78 ; CHECK-NEXT: fptoui float %1 to i64 79 define i64 @t8(float %a) { 80 %1 = fcmp ult float %a, 5.0 81 %2 = fptoui float %a to i64 82 %3 = select i1 %1, i64 %2, i64 5 83 ret i64 %3 84 } 85 86 ; CHECK-LABEL: @t9 87 ; CHECK-NEXT: fcmp oge float %a, 0.000000e+00 88 ; CHECK-NEXT: select i1 %.inv, float 0.000000e+00, float %a 89 ; CHECK-NEXT: fptosi float %1 to i8 90 define i8 @t9(float %a) { 91 %1 = fcmp ult float %a, 0.0 92 %2 = fptosi float %a to i8 93 %3 = select i1 %1, i8 %2, i8 0 94 ret i8 %3 95 } 96 97 ; CHECK-LABEL: @t11 98 ; CHECK-NEXT: fcmp fast oge float %b, %a 99 ; CHECK-NEXT: select i1 %.inv, float %a, float %b 100 ; CHECK-NEXT: fptosi 101 define i8 @t11(float %a, float %b) { 102 ; Either operand could be NaN, but fast modifier applied. 103 %1 = fcmp fast ult float %b, %a 104 %2 = fptosi float %a to i8 105 %3 = fptosi float %b to i8 106 %4 = select i1 %1, i8 %3, i8 %2 107 ret i8 %4 108 } 109 110 ; CHECK-LABEL: @t12 111 ; CHECK-NEXT: fcmp nnan oge float %b, %a 112 ; CHECK-NEXT: select i1 %.inv, float %a, float %b 113 ; CHECK-NEXT: fptosi float %.v to i8 114 define i8 @t12(float %a, float %b) { 115 ; Either operand could be NaN, but nnan modifier applied. 116 %1 = fcmp nnan ult float %b, %a 117 %2 = fptosi float %a to i8 118 %3 = fptosi float %b to i8 119 %4 = select i1 %1, i8 %3, i8 %2 120 ret i8 %4 121 } 122 123 ; CHECK-LABEL: @t13 124 ; CHECK-NEXT: fcmp ult float %a, 1.500000e+00 125 ; CHECK-NEXT: fptosi float %a to i8 126 ; CHECK-NEXT: select i1 %1, i8 %2, i8 1 127 define i8 @t13(float %a) { 128 ; Float and int values do not match. 129 %1 = fcmp ult float %a, 1.5 130 %2 = fptosi float %a to i8 131 %3 = select i1 %1, i8 %2, i8 1 132 ret i8 %3 133 } 134 135 ; CHECK-LABEL: @t14 136 ; CHECK-NEXT: fcmp ule float %a, 0.000000e+00 137 ; CHECK-NEXT: fptosi float %a to i8 138 ; CHECK-NEXT: select i1 %1, i8 %2, i8 0 139 define i8 @t14(float %a) { 140 ; <= comparison, where %a could be -0.0. Not safe. 141 %1 = fcmp ule float %a, 0.0 142 %2 = fptosi float %a to i8 143 %3 = select i1 %1, i8 %2, i8 0 144 ret i8 %3 145 } 146 147 ; CHECK-LABEL: @t15 148 ; CHECK-NEXT: fcmp nsz oge float %a, 0.000000e+00 149 ; CHECK-NEXT: select i1 %.inv, float 0.000000e+00, float %a 150 ; CHECK-NEXT: fptosi float %1 to i8 151 define i8 @t15(float %a) { 152 %1 = fcmp nsz ule float %a, 0.0 153 %2 = fptosi float %a to i8 154 %3 = select i1 %1, i8 %2, i8 0 155 ret i8 %3 156 } 157