418 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i1 @test1(i8 %A) {5; CHECK-LABEL: @test1(6; CHECK-NEXT: ret i1 true7;8 %B = sitofp i8 %A to double9 %C = fcmp ult double %B, 128.010 ret i1 %C11}12 13define i1 @test2(i8 %A) {14; CHECK-LABEL: @test2(15; CHECK-NEXT: ret i1 true16;17 %B = sitofp i8 %A to double18 %C = fcmp ugt double %B, -128.119 ret i1 %C20}21 22define i1 @test3(i8 %A) {23; CHECK-LABEL: @test3(24; CHECK-NEXT: ret i1 true25;26 %B = sitofp i8 %A to double27 %C = fcmp ule double %B, 127.028 ret i1 %C29}30 31define i1 @test4(i8 %A) {32; CHECK-LABEL: @test4(33; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A:%.*]], 12734; CHECK-NEXT: ret i1 [[C]]35;36 %B = sitofp i8 %A to double37 %C = fcmp ult double %B, 127.038 ret i1 %C39}40 41define i32 @test5(i32 %A) {42; CHECK-LABEL: @test5(43; CHECK-NEXT: ret i32 [[A:%.*]]44;45 %B = sitofp i32 %A to double46 %C = fptosi double %B to i3247 %D = uitofp i32 %C to double48 %E = fptoui double %D to i3249 ret i32 %E50}51 52define i32 @test6(i32 %A) {53; CHECK-LABEL: @test6(54; CHECK-NEXT: [[ADDCONV:%.*]] = and i32 [[A:%.*]], 3955; CHECK-NEXT: ret i32 [[ADDCONV]]56;57 %B = and i32 %A, 758 %C = and i32 %A, 3259 %D = sitofp i32 %B to double60 %E = sitofp i32 %C to double61 %F = fadd double %D, %E62 %G = fptosi double %F to i3263 ret i32 %G64}65 66define i32 @test7(i32 %A) {67; CHECK-LABEL: @test7(68; CHECK-NEXT: ret i32 [[A:%.*]]69;70 %B = sitofp i32 %A to double71 %C = fptoui double %B to i3272 ret i32 %C73}74 75define i32 @test8(i32 %A) {76; CHECK-LABEL: @test8(77; CHECK-NEXT: ret i32 [[A:%.*]]78;79 %B = uitofp i32 %A to double80 %C = fptosi double %B to i3281 ret i32 %C82}83 84define i32 @test9(i8 %A) {85; CHECK-LABEL: @test9(86; CHECK-NEXT: [[C:%.*]] = zext i8 [[A:%.*]] to i3287; CHECK-NEXT: ret i32 [[C]]88;89 %B = sitofp i8 %A to float90 %C = fptoui float %B to i3291 ret i32 %C92}93 94define i32 @test10(i8 %A) {95; CHECK-LABEL: @test10(96; CHECK-NEXT: [[C:%.*]] = sext i8 [[A:%.*]] to i3297; CHECK-NEXT: ret i32 [[C]]98;99 %B = sitofp i8 %A to float100 %C = fptosi float %B to i32101 ret i32 %C102}103 104; If the input value is outside of the range of the output cast, it's105; undefined behavior, so we can assume it fits.106 107define i8 @test11(i32 %A) {108; CHECK-LABEL: @test11(109; CHECK-NEXT: [[C:%.*]] = trunc i32 [[A:%.*]] to i8110; CHECK-NEXT: ret i8 [[C]]111;112 %B = sitofp i32 %A to float113 %C = fptosi float %B to i8114 ret i8 %C115}116 117; If the input value is negative, it'll be outside the range of the118; output cast, and thus undefined behavior.119 120define i32 @test12(i8 %A) {121; CHECK-LABEL: @test12(122; CHECK-NEXT: [[C:%.*]] = zext i8 [[A:%.*]] to i32123; CHECK-NEXT: ret i32 [[C]]124;125 %B = sitofp i8 %A to float126 %C = fptoui float %B to i32127 ret i32 %C128}129 130; This can't fold because the 25-bit input doesn't fit in the mantissa.131 132define i32 @test13(i25 %A) {133; CHECK-LABEL: @test13(134; CHECK-NEXT: [[B:%.*]] = uitofp i25 [[A:%.*]] to float135; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32136; CHECK-NEXT: ret i32 [[C]]137;138 %B = uitofp i25 %A to float139 %C = fptoui float %B to i32140 ret i32 %C141}142 143; But this one can.144 145define i32 @test14(i24 %A) {146; CHECK-LABEL: @test14(147; CHECK-NEXT: [[C:%.*]] = zext i24 [[A:%.*]] to i32148; CHECK-NEXT: ret i32 [[C]]149;150 %B = uitofp i24 %A to float151 %C = fptoui float %B to i32152 ret i32 %C153}154 155; And this one can too.156 157define i24 @test15(i32 %A) {158; CHECK-LABEL: @test15(159; CHECK-NEXT: [[C:%.*]] = trunc i32 [[A:%.*]] to i24160; CHECK-NEXT: ret i24 [[C]]161;162 %B = uitofp i32 %A to float163 %C = fptoui float %B to i24164 ret i24 %C165}166 167; This can fold because the 25-bit input is signed and we discard the sign bit.168 169define i32 @test16(i25 %A) {170; CHECK-LABEL: @test16(171; CHECK-NEXT: [[C:%.*]] = zext i25 [[A:%.*]] to i32172; CHECK-NEXT: ret i32 [[C]]173;174 %B = sitofp i25 %A to float175 %C = fptoui float %B to i32176 ret i32 %C177}178 179; This can't fold because the 26-bit input won't fit the mantissa180; even after discarding the signed bit.181 182define i32 @test17(i26 %A) {183; CHECK-LABEL: @test17(184; CHECK-NEXT: [[B:%.*]] = sitofp i26 [[A:%.*]] to float185; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32186; CHECK-NEXT: ret i32 [[C]]187;188 %B = sitofp i26 %A to float189 %C = fptoui float %B to i32190 ret i32 %C191}192 193; This can't fold because the 54-bit output is big enough to hold an input194; that was rounded when converted to double.195 196define i54 @test18(i64 %A) {197; CHECK-LABEL: @test18(198; CHECK-NEXT: [[B:%.*]] = sitofp i64 [[A:%.*]] to double199; CHECK-NEXT: [[C:%.*]] = fptosi double [[B]] to i54200; CHECK-NEXT: ret i54 [[C]]201;202 %B = sitofp i64 %A to double203 %C = fptosi double %B to i54204 ret i54 %C205}206 207; This can't fold because the 55-bit output won't fit the mantissa208; even after discarding the sign bit.209 210define i55 @test19(i64 %A) {211; CHECK-LABEL: @test19(212; CHECK-NEXT: [[B:%.*]] = sitofp i64 [[A:%.*]] to double213; CHECK-NEXT: [[C:%.*]] = fptosi double [[B]] to i55214; CHECK-NEXT: ret i55 [[C]]215;216 %B = sitofp i64 %A to double217 %C = fptosi double %B to i55218 ret i55 %C219}220 221; The mask guarantees that the input is small enough to eliminate the FP casts.222 223define i25 @masked_input(i25 %A) {224; CHECK-LABEL: @masked_input(225; CHECK-NEXT: [[M:%.*]] = and i25 [[A:%.*]], 65535226; CHECK-NEXT: ret i25 [[M]]227;228 %m = and i25 %A, 65535229 %B = uitofp i25 %m to float230 %C = fptoui float %B to i25231 ret i25 %C232}233 234define i25 @max_masked_input(i25 %A) {235; CHECK-LABEL: @max_masked_input(236; CHECK-NEXT: [[M:%.*]] = and i25 [[A:%.*]], 16777215237; CHECK-NEXT: ret i25 [[M]]238;239 %m = and i25 %A, 16777215 ; max intermediate 16777215 (= 1 << 24)-1240 %B = uitofp i25 %m to float241 %C = fptoui float %B to i25242 ret i25 %C243}244 245define i25 @consider_lowbits_masked_input(i25 %A) {246; CHECK-LABEL: @consider_lowbits_masked_input(247; CHECK-NEXT: [[M:%.*]] = and i25 [[A:%.*]], -16777214248; CHECK-NEXT: ret i25 [[M]]249;250 %m = and i25 %A, 16777218 ; Make use of the low zero bits - intermediate 16777218 (= 1 << 24 + 2)251 %B = uitofp i25 %m to float252 %C = fptoui float %B to i25253 ret i25 %C254}255 256define i32 @overflow_masked_input(i32 %A) {257; CHECK-LABEL: @overflow_masked_input(258; CHECK-NEXT: [[M:%.*]] = and i32 [[A:%.*]], 16777217259; CHECK-NEXT: [[B:%.*]] = uitofp nneg i32 [[M]] to float260; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32261; CHECK-NEXT: ret i32 [[C]]262;263 %m = and i32 %A, 16777217 ; Negative test - intermediate 16777217 (= 1 << 24 + 1)264 %B = uitofp i32 %m to float265 %C = fptoui float %B to i32266 ret i32 %C267}268 269; Clear the low bit - guarantees that the input is converted to FP without rounding.270 271define i25 @low_masked_input(i25 %A) {272; CHECK-LABEL: @low_masked_input(273; CHECK-NEXT: [[M:%.*]] = and i25 [[A:%.*]], -2274; CHECK-NEXT: ret i25 [[M]]275;276 %m = and i25 %A, -2277 %B = uitofp i25 %m to float278 %C = fptoui float %B to i25279 ret i25 %C280}281 282; Output is small enough to ensure exact cast (overflow produces poison).283 284define i11 @s32_half_s11(i32 %x) {285; CHECK-LABEL: @s32_half_s11(286; CHECK-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i11287; CHECK-NEXT: ret i11 [[R]]288;289 %h = sitofp i32 %x to half290 %r = fptosi half %h to i11291 ret i11 %r292}293 294; Output is small enough to ensure exact cast (overflow produces poison).295 296define i11 @s32_half_u11(i32 %x) {297; CHECK-LABEL: @s32_half_u11(298; CHECK-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i11299; CHECK-NEXT: ret i11 [[R]]300;301 %h = sitofp i32 %x to half302 %r = fptoui half %h to i11303 ret i11 %r304}305 306; Output is small enough to ensure exact cast (overflow produces poison).307 308define i11 @u32_half_s11(i32 %x) {309; CHECK-LABEL: @u32_half_s11(310; CHECK-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i11311; CHECK-NEXT: ret i11 [[R]]312;313 %h = uitofp i32 %x to half314 %r = fptosi half %h to i11315 ret i11 %r316}317 318; Output is small enough to ensure exact cast (overflow produces poison).319 320define i11 @u32_half_u11(i32 %x) {321; CHECK-LABEL: @u32_half_u11(322; CHECK-NEXT: [[R:%.*]] = trunc i32 [[X:%.*]] to i11323; CHECK-NEXT: ret i11 [[R]]324;325 %h = uitofp i32 %x to half326 %r = fptoui half %h to i11327 ret i11 %r328}329 330; Too many bits in output to ensure exact cast.331 332define i12 @s32_half_s12(i32 %x) {333; CHECK-LABEL: @s32_half_s12(334; CHECK-NEXT: [[H:%.*]] = sitofp i32 [[X:%.*]] to half335; CHECK-NEXT: [[R:%.*]] = fptosi half [[H]] to i12336; CHECK-NEXT: ret i12 [[R]]337;338 %h = sitofp i32 %x to half339 %r = fptosi half %h to i12340 ret i12 %r341}342 343; Too many bits in output to ensure exact cast.344 345define i12 @s32_half_u12(i32 %x) {346; CHECK-LABEL: @s32_half_u12(347; CHECK-NEXT: [[H:%.*]] = sitofp i32 [[X:%.*]] to half348; CHECK-NEXT: [[R:%.*]] = fptoui half [[H]] to i12349; CHECK-NEXT: ret i12 [[R]]350;351 %h = sitofp i32 %x to half352 %r = fptoui half %h to i12353 ret i12 %r354}355 356; TODO: This is safe to convert to trunc.357 358define i12 @u32_half_s12(i32 %x) {359; CHECK-LABEL: @u32_half_s12(360; CHECK-NEXT: [[H:%.*]] = uitofp i32 [[X:%.*]] to half361; CHECK-NEXT: [[R:%.*]] = fptosi half [[H]] to i12362; CHECK-NEXT: ret i12 [[R]]363;364 %h = uitofp i32 %x to half365 %r = fptosi half %h to i12366 ret i12 %r367}368 369; Too many bits in output to ensure exact cast.370 371define i12 @u32_half_u12(i32 %x) {372; CHECK-LABEL: @u32_half_u12(373; CHECK-NEXT: [[H:%.*]] = uitofp i32 [[X:%.*]] to half374; CHECK-NEXT: [[R:%.*]] = fptoui half [[H]] to i12375; CHECK-NEXT: ret i12 [[R]]376;377 %h = uitofp i32 %x to half378 %r = fptoui half %h to i12379 ret i12 %r380}381 382define <2 x i1> @i8_vec_sitofp_test1(<2 x i8> %A) {383; CHECK-LABEL: @i8_vec_sitofp_test1(384; CHECK-NEXT: ret <2 x i1> splat (i1 true)385;386 %B = sitofp <2 x i8> %A to <2 x double>387 %C = fcmp ult <2 x double> %B, <double 128.0, double 128.0>388 ret <2 x i1> %C389}390 391define <2 x i1> @i8_vec_sitofp_test2(<2 x i8> %A) {392; CHECK-LABEL: @i8_vec_sitofp_test2(393; CHECK-NEXT: ret <2 x i1> splat (i1 true)394;395 %B = sitofp <2 x i8> %A to <2 x double>396 %C = fcmp ugt <2 x double> %B, <double -128.1, double -128.1>397 ret <2 x i1> %C398}399 400define <2 x i1> @i8_vec_sitofp_test3(<2 x i8> %A) {401; CHECK-LABEL: @i8_vec_sitofp_test3(402; CHECK-NEXT: ret <2 x i1> splat (i1 true)403;404 %B = sitofp <2 x i8> %A to <2 x double>405 %C = fcmp ule <2 x double> %B, <double 127.0, double 127.0>406 ret <2 x i1> %C407}408 409define <2 x i1> @i8_vec_sitofp_test4(<2 x i8> %A) {410; CHECK-LABEL: @i8_vec_sitofp_test4(411; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 127)412; CHECK-NEXT: ret <2 x i1> [[C]]413;414 %B = sitofp <2 x i8> %A to <2 x double>415 %C = fcmp ult <2 x double> %B, <double 127.0, double 127.0>416 ret <2 x i1> %C417}418