1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -float2int -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -passes='float2int' -S | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; 5*9880d681SAndroid Build Coastguard Worker; Positive tests 6*9880d681SAndroid Build Coastguard Worker; 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple1 9*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 10*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = add i32 %1, 1 11*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = trunc i32 %2 to i16 12*9880d681SAndroid Build Coastguard Worker; CHECK: ret i16 %3 13*9880d681SAndroid Build Coastguard Workerdefine i16 @simple1(i8 %a) { 14*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 15*9880d681SAndroid Build Coastguard Worker %2 = fadd float %1, 1.0 16*9880d681SAndroid Build Coastguard Worker %3 = fptoui float %2 to i16 17*9880d681SAndroid Build Coastguard Worker ret i16 %3 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple2 21*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 22*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = sub i32 %1, 1 23*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = trunc i32 %2 to i8 24*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %3 25*9880d681SAndroid Build Coastguard Workerdefine i8 @simple2(i8 %a) { 26*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 27*9880d681SAndroid Build Coastguard Worker %2 = fsub float %1, 1.0 28*9880d681SAndroid Build Coastguard Worker %3 = fptoui float %2 to i8 29*9880d681SAndroid Build Coastguard Worker ret i8 %3 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple3 33*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 34*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = sub i32 %1, 1 35*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %2 36*9880d681SAndroid Build Coastguard Workerdefine i32 @simple3(i8 %a) { 37*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 38*9880d681SAndroid Build Coastguard Worker %2 = fsub float %1, 1.0 39*9880d681SAndroid Build Coastguard Worker %3 = fptoui float %2 to i32 40*9880d681SAndroid Build Coastguard Worker ret i32 %3 41*9880d681SAndroid Build Coastguard Worker} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @cmp 44*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 45*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = zext i8 %b to i32 46*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = icmp slt i32 %1, %2 47*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 %3 48*9880d681SAndroid Build Coastguard Workerdefine i1 @cmp(i8 %a, i8 %b) { 49*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 50*9880d681SAndroid Build Coastguard Worker %2 = uitofp i8 %b to float 51*9880d681SAndroid Build Coastguard Worker %3 = fcmp ult float %1, %2 52*9880d681SAndroid Build Coastguard Worker ret i1 %3 53*9880d681SAndroid Build Coastguard Worker} 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple4 56*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i32 %a to i64 57*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = add i64 %1, 1 58*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = trunc i64 %2 to i32 59*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %3 60*9880d681SAndroid Build Coastguard Workerdefine i32 @simple4(i32 %a) { 61*9880d681SAndroid Build Coastguard Worker %1 = uitofp i32 %a to double 62*9880d681SAndroid Build Coastguard Worker %2 = fadd double %1, 1.0 63*9880d681SAndroid Build Coastguard Worker %3 = fptoui double %2 to i32 64*9880d681SAndroid Build Coastguard Worker ret i32 %3 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple5 68*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 69*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = zext i8 %b to i32 70*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = add i32 %1, 1 71*9880d681SAndroid Build Coastguard Worker; CHECK: %4 = mul i32 %3, %2 72*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %4 73*9880d681SAndroid Build Coastguard Workerdefine i32 @simple5(i8 %a, i8 %b) { 74*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 75*9880d681SAndroid Build Coastguard Worker %2 = uitofp i8 %b to float 76*9880d681SAndroid Build Coastguard Worker %3 = fadd float %1, 1.0 77*9880d681SAndroid Build Coastguard Worker %4 = fmul float %3, %2 78*9880d681SAndroid Build Coastguard Worker %5 = fptoui float %4 to i32 79*9880d681SAndroid Build Coastguard Worker ret i32 %5 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; The two chains don't interact - failure of one shouldn't 83*9880d681SAndroid Build Coastguard Worker; cause failure of the other. 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @multi1 86*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 87*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = zext i8 %b to i32 88*9880d681SAndroid Build Coastguard Worker; CHECK: %fc = uitofp i8 %c to float 89*9880d681SAndroid Build Coastguard Worker; CHECK: %x1 = add i32 %1, %2 90*9880d681SAndroid Build Coastguard Worker; CHECK: %z = fadd float %fc, %d 91*9880d681SAndroid Build Coastguard Worker; CHECK: %w = fptoui float %z to i32 92*9880d681SAndroid Build Coastguard Worker; CHECK: %r = add i32 %x1, %w 93*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %r 94*9880d681SAndroid Build Coastguard Workerdefine i32 @multi1(i8 %a, i8 %b, i8 %c, float %d) { 95*9880d681SAndroid Build Coastguard Worker %fa = uitofp i8 %a to float 96*9880d681SAndroid Build Coastguard Worker %fb = uitofp i8 %b to float 97*9880d681SAndroid Build Coastguard Worker %fc = uitofp i8 %c to float 98*9880d681SAndroid Build Coastguard Worker %x = fadd float %fa, %fb 99*9880d681SAndroid Build Coastguard Worker %y = fptoui float %x to i32 100*9880d681SAndroid Build Coastguard Worker %z = fadd float %fc, %d 101*9880d681SAndroid Build Coastguard Worker %w = fptoui float %z to i32 102*9880d681SAndroid Build Coastguard Worker %r = add i32 %y, %w 103*9880d681SAndroid Build Coastguard Worker ret i32 %r 104*9880d681SAndroid Build Coastguard Worker} 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple_negzero 107*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = zext i8 %a to i32 108*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = add i32 %1, 0 109*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = trunc i32 %2 to i16 110*9880d681SAndroid Build Coastguard Worker; CHECK: ret i16 %3 111*9880d681SAndroid Build Coastguard Workerdefine i16 @simple_negzero(i8 %a) { 112*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 113*9880d681SAndroid Build Coastguard Worker %2 = fadd fast float %1, -0.0 114*9880d681SAndroid Build Coastguard Worker %3 = fptoui float %2 to i16 115*9880d681SAndroid Build Coastguard Worker ret i16 %3 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @simple_negative 119*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = sext i8 %call to i32 120*9880d681SAndroid Build Coastguard Worker; CHECK: %mul1 = mul i32 %1, -3 121*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = trunc i32 %mul1 to i8 122*9880d681SAndroid Build Coastguard Worker; CHECK: %conv3 = sext i8 %2 to i32 123*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %conv3 124*9880d681SAndroid Build Coastguard Workerdefine i32 @simple_negative(i8 %call) { 125*9880d681SAndroid Build Coastguard Worker %conv1 = sitofp i8 %call to float 126*9880d681SAndroid Build Coastguard Worker %mul = fmul float %conv1, -3.000000e+00 127*9880d681SAndroid Build Coastguard Worker %conv2 = fptosi float %mul to i8 128*9880d681SAndroid Build Coastguard Worker %conv3 = sext i8 %conv2 to i32 129*9880d681SAndroid Build Coastguard Worker ret i32 %conv3 130*9880d681SAndroid Build Coastguard Worker} 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; 133*9880d681SAndroid Build Coastguard Worker; Negative tests 134*9880d681SAndroid Build Coastguard Worker; 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_multi1 137*9880d681SAndroid Build Coastguard Worker; CHECK: %fa = uitofp i8 %a to float 138*9880d681SAndroid Build Coastguard Worker; CHECK: %fc = uitofp i8 %c to float 139*9880d681SAndroid Build Coastguard Worker; CHECK: %x = fadd float %fa, %fc 140*9880d681SAndroid Build Coastguard Worker; CHECK: %y = fptoui float %x to i32 141*9880d681SAndroid Build Coastguard Worker; CHECK: %z = fadd float %fc, %d 142*9880d681SAndroid Build Coastguard Worker; CHECK: %w = fptoui float %z to i32 143*9880d681SAndroid Build Coastguard Worker; CHECK: %r = add i32 %y, %w 144*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %r 145*9880d681SAndroid Build Coastguard Worker; The two chains intersect, which means because one fails, no 146*9880d681SAndroid Build Coastguard Worker; transform can occur. 147*9880d681SAndroid Build Coastguard Workerdefine i32 @neg_multi1(i8 %a, i8 %b, i8 %c, float %d) { 148*9880d681SAndroid Build Coastguard Worker %fa = uitofp i8 %a to float 149*9880d681SAndroid Build Coastguard Worker %fc = uitofp i8 %c to float 150*9880d681SAndroid Build Coastguard Worker %x = fadd float %fa, %fc 151*9880d681SAndroid Build Coastguard Worker %y = fptoui float %x to i32 152*9880d681SAndroid Build Coastguard Worker %z = fadd float %fc, %d 153*9880d681SAndroid Build Coastguard Worker %w = fptoui float %z to i32 154*9880d681SAndroid Build Coastguard Worker %r = add i32 %y, %w 155*9880d681SAndroid Build Coastguard Worker ret i32 %r 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_muld 159*9880d681SAndroid Build Coastguard Worker; CHECK: %fa = uitofp i32 %a to double 160*9880d681SAndroid Build Coastguard Worker; CHECK: %fb = uitofp i32 %b to double 161*9880d681SAndroid Build Coastguard Worker; CHECK: %mul = fmul double %fa, %fb 162*9880d681SAndroid Build Coastguard Worker; CHECK: %r = fptoui double %mul to i64 163*9880d681SAndroid Build Coastguard Worker; CHECK: ret i64 %r 164*9880d681SAndroid Build Coastguard Worker; The i32 * i32 = i64, which has 64 bits, which is greater than the 52 bits 165*9880d681SAndroid Build Coastguard Worker; that can be exactly represented in a double. 166*9880d681SAndroid Build Coastguard Workerdefine i64 @neg_muld(i32 %a, i32 %b) { 167*9880d681SAndroid Build Coastguard Worker %fa = uitofp i32 %a to double 168*9880d681SAndroid Build Coastguard Worker %fb = uitofp i32 %b to double 169*9880d681SAndroid Build Coastguard Worker %mul = fmul double %fa, %fb 170*9880d681SAndroid Build Coastguard Worker %r = fptoui double %mul to i64 171*9880d681SAndroid Build Coastguard Worker ret i64 %r 172*9880d681SAndroid Build Coastguard Worker} 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_mulf 175*9880d681SAndroid Build Coastguard Worker; CHECK: %fa = uitofp i16 %a to float 176*9880d681SAndroid Build Coastguard Worker; CHECK: %fb = uitofp i16 %b to float 177*9880d681SAndroid Build Coastguard Worker; CHECK: %mul = fmul float %fa, %fb 178*9880d681SAndroid Build Coastguard Worker; CHECK: %r = fptoui float %mul to i32 179*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %r 180*9880d681SAndroid Build Coastguard Worker; The i16 * i16 = i32, which can't be represented in a float, but can in a 181*9880d681SAndroid Build Coastguard Worker; double. This should fail, as the written code uses floats, not doubles so 182*9880d681SAndroid Build Coastguard Worker; the original result may be inaccurate. 183*9880d681SAndroid Build Coastguard Workerdefine i32 @neg_mulf(i16 %a, i16 %b) { 184*9880d681SAndroid Build Coastguard Worker %fa = uitofp i16 %a to float 185*9880d681SAndroid Build Coastguard Worker %fb = uitofp i16 %b to float 186*9880d681SAndroid Build Coastguard Worker %mul = fmul float %fa, %fb 187*9880d681SAndroid Build Coastguard Worker %r = fptoui float %mul to i32 188*9880d681SAndroid Build Coastguard Worker ret i32 %r 189*9880d681SAndroid Build Coastguard Worker} 190*9880d681SAndroid Build Coastguard Worker 191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_cmp 192*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = uitofp i8 %a to float 193*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = uitofp i8 %b to float 194*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = fcmp false float %1, %2 195*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 %3 196*9880d681SAndroid Build Coastguard Worker; "false" doesn't have an icmp equivalent. 197*9880d681SAndroid Build Coastguard Workerdefine i1 @neg_cmp(i8 %a, i8 %b) { 198*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 199*9880d681SAndroid Build Coastguard Worker %2 = uitofp i8 %b to float 200*9880d681SAndroid Build Coastguard Worker %3 = fcmp false float %1, %2 201*9880d681SAndroid Build Coastguard Worker ret i1 %3 202*9880d681SAndroid Build Coastguard Worker} 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_div 205*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = uitofp i8 %a to float 206*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = fdiv float %1, 1.0 207*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = fptoui float %2 to i16 208*9880d681SAndroid Build Coastguard Worker; CHECK: ret i16 %3 209*9880d681SAndroid Build Coastguard Worker; Division isn't a supported operator. 210*9880d681SAndroid Build Coastguard Workerdefine i16 @neg_div(i8 %a) { 211*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 212*9880d681SAndroid Build Coastguard Worker %2 = fdiv float %1, 1.0 213*9880d681SAndroid Build Coastguard Worker %3 = fptoui float %2 to i16 214*9880d681SAndroid Build Coastguard Worker ret i16 %3 215*9880d681SAndroid Build Coastguard Worker} 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_remainder 218*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = uitofp i8 %a to float 219*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = fadd float %1, 1.2 220*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = fptoui float %2 to i16 221*9880d681SAndroid Build Coastguard Worker; CHECK: ret i16 %3 222*9880d681SAndroid Build Coastguard Worker; 1.2 is not an integer. 223*9880d681SAndroid Build Coastguard Workerdefine i16 @neg_remainder(i8 %a) { 224*9880d681SAndroid Build Coastguard Worker %1 = uitofp i8 %a to float 225*9880d681SAndroid Build Coastguard Worker %2 = fadd float %1, 1.25 226*9880d681SAndroid Build Coastguard Worker %3 = fptoui float %2 to i16 227*9880d681SAndroid Build Coastguard Worker ret i16 %3 228*9880d681SAndroid Build Coastguard Worker} 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_toolarge 231*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = uitofp i80 %a to fp128 232*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = fadd fp128 %1, %1 233*9880d681SAndroid Build Coastguard Worker; CHECK: %3 = fptoui fp128 %2 to i80 234*9880d681SAndroid Build Coastguard Worker; CHECK: ret i80 %3 235*9880d681SAndroid Build Coastguard Worker; i80 > i64, which is the largest bitwidth handleable by default. 236*9880d681SAndroid Build Coastguard Workerdefine i80 @neg_toolarge(i80 %a) { 237*9880d681SAndroid Build Coastguard Worker %1 = uitofp i80 %a to fp128 238*9880d681SAndroid Build Coastguard Worker %2 = fadd fp128 %1, %1 239*9880d681SAndroid Build Coastguard Worker %3 = fptoui fp128 %2 to i80 240*9880d681SAndroid Build Coastguard Worker ret i80 %3 241*9880d681SAndroid Build Coastguard Worker} 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_calluser 244*9880d681SAndroid Build Coastguard Worker; CHECK: sitofp 245*9880d681SAndroid Build Coastguard Worker; CHECK: fcmp 246*9880d681SAndroid Build Coastguard Worker; The sequence %1..%3 cannot be converted because %4 uses %2. 247*9880d681SAndroid Build Coastguard Workerdefine i32 @neg_calluser(i32 %value) { 248*9880d681SAndroid Build Coastguard Worker %1 = sitofp i32 %value to double 249*9880d681SAndroid Build Coastguard Worker %2 = fadd double %1, 1.0 250*9880d681SAndroid Build Coastguard Worker %3 = fcmp olt double %2, 0.000000e+00 251*9880d681SAndroid Build Coastguard Worker %4 = tail call double @g(double %2) 252*9880d681SAndroid Build Coastguard Worker %5 = fptosi double %4 to i32 253*9880d681SAndroid Build Coastguard Worker %6 = zext i1 %3 to i32 254*9880d681SAndroid Build Coastguard Worker %7 = add i32 %6, %5 255*9880d681SAndroid Build Coastguard Worker ret i32 %7 256*9880d681SAndroid Build Coastguard Worker} 257*9880d681SAndroid Build Coastguard Workerdeclare double @g(double) 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @neg_vector 260*9880d681SAndroid Build Coastguard Worker; CHECK: %1 = uitofp <4 x i8> %a to <4 x float> 261*9880d681SAndroid Build Coastguard Worker; CHECK: %2 = fptoui <4 x float> %1 to <4 x i16> 262*9880d681SAndroid Build Coastguard Worker; CHECK: ret <4 x i16> %2 263*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @neg_vector(<4 x i8> %a) { 264*9880d681SAndroid Build Coastguard Worker %1 = uitofp <4 x i8> %a to <4 x float> 265*9880d681SAndroid Build Coastguard Worker %2 = fptoui <4 x float> %1 to <4 x i16> 266*9880d681SAndroid Build Coastguard Worker ret <4 x i16> %2 267*9880d681SAndroid Build Coastguard Worker} 268