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 7define 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 19define 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 31define 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 43define 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 55define 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 67define 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 79define 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 90define 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 101define 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 114define 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 127define 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 139define 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 151define 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 158; CHECK-LABEL: @t16 159; CHECK: %[[cmp:.*]] = icmp sgt i32 %x, 0 160; CHECK: %[[cst:.*]] = sitofp i32 %x to double 161; CHECK: %[[sel:.*]] = select i1 %[[cmp]], double %[[cst]], double 5.000000e-01 162; CHECK: ret double %[[sel]] 163define double @t16(i32 %x) { 164entry: 165 %cmp = icmp sgt i32 %x, 0 166 %cst = sitofp i32 %x to double 167 %sel = select i1 %cmp, double %cst, double 5.000000e-01 168 ret double %sel 169} 170 171; CHECK-LABEL: @t17 172; CHECK: %[[cmp:.*]] = icmp sgt i32 %x, 2 173; CHECK: %[[sel:.*]] = select i1 %[[cmp]], i32 %x, i32 2 174; CHECK: %[[cst:.*]] = sitofp i32 %[[sel]] to double 175; CHECK: ret double %[[cst]] 176define double @t17(i32 %x) { 177entry: 178 %cmp = icmp sgt i32 %x, 2 179 %cst = sitofp i32 %x to double 180 %sel = select i1 %cmp, double %cst, double 2.0 181 ret double %sel 182} 183