556 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Test some floating point casting cases3; RUN: opt < %s -passes=instcombine -S | FileCheck %s4 5define i8 @test1() {6; CHECK-LABEL: @test1(7; CHECK-NEXT: ret i8 -18;9 %x = fptoui float 2.550000e+02 to i810 ret i8 %x11}12 13define i8 @test2() {14; CHECK-LABEL: @test2(15; CHECK-NEXT: ret i8 -116;17 %x = fptosi float -1.000000e+00 to i818 ret i8 %x19}20 21define half @test3(float %a) {22; CHECK-LABEL: @test3(23; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half24; CHECK-NEXT: [[C:%.*]] = call half @llvm.fabs.f16(half [[TMP1]])25; CHECK-NEXT: ret half [[C]]26;27 %b = call float @llvm.fabs.f32(float %a)28 %c = fptrunc float %b to half29 ret half %c30}31 32define half @test3_fast(float %a) {33; CHECK-LABEL: @test3_fast(34; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half35; CHECK-NEXT: [[C:%.*]] = call fast half @llvm.fabs.f16(half [[TMP1]])36; CHECK-NEXT: ret half [[C]]37;38 %b = call float @llvm.fabs.f32(float %a)39 %c = fptrunc fast float %b to half40 ret half %c41}42 43define half @test3_both_ninf(float %a) {44; CHECK-LABEL: @test3_both_ninf(45; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half46; CHECK-NEXT: [[C:%.*]] = call ninf half @llvm.fabs.f16(half [[TMP1]])47; CHECK-NEXT: ret half [[C]]48;49 %b = call ninf float @llvm.fabs.f32(float %a)50 %c = fptrunc ninf float %b to half51 ret half %c52}53 54define half @test3_fabs_ninf(float %a) {55; CHECK-LABEL: @test3_fabs_ninf(56; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half57; CHECK-NEXT: [[C:%.*]] = call half @llvm.fabs.f16(half [[TMP1]])58; CHECK-NEXT: ret half [[C]]59;60 %b = call ninf float @llvm.fabs.f32(float %a)61 %c = fptrunc float %b to half62 ret half %c63}64 65define half @test3_fptrunc_ninf(float %a) {66; CHECK-LABEL: @test3_fptrunc_ninf(67; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half68; CHECK-NEXT: [[C:%.*]] = call ninf half @llvm.fabs.f16(half [[TMP1]])69; CHECK-NEXT: ret half [[C]]70;71 %b = call float @llvm.fabs.f32(float %a)72 %c = fptrunc ninf float %b to half73 ret half %c74}75 76define half @fneg_fptrunc(float %a) {77; CHECK-LABEL: @fneg_fptrunc(78; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half79; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]80; CHECK-NEXT: ret half [[C]]81;82 %b = fsub float -0.0, %a83 %c = fptrunc float %b to half84 ret half %c85}86 87define half @unary_fneg_fptrunc(float %a) {88; CHECK-LABEL: @unary_fneg_fptrunc(89; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half90; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]91; CHECK-NEXT: ret half [[C]]92;93 %b = fneg float %a94 %c = fptrunc float %b to half95 ret half %c96}97 98define <2 x half> @fneg_fptrunc_vec_poison(<2 x float> %a) {99; CHECK-LABEL: @fneg_fptrunc_vec_poison(100; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x float> [[A:%.*]] to <2 x half>101; CHECK-NEXT: [[C:%.*]] = fneg <2 x half> [[TMP1]]102; CHECK-NEXT: ret <2 x half> [[C]]103;104 %b = fsub <2 x float> <float -0.0, float poison>, %a105 %c = fptrunc <2 x float> %b to <2 x half>106 ret <2 x half> %c107}108 109define <2 x half> @unary_fneg_fptrunc_vec(<2 x float> %a) {110; CHECK-LABEL: @unary_fneg_fptrunc_vec(111; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x float> [[A:%.*]] to <2 x half>112; CHECK-NEXT: [[C:%.*]] = fneg <2 x half> [[TMP1]]113; CHECK-NEXT: ret <2 x half> [[C]]114;115 %b = fneg <2 x float> %a116 %c = fptrunc <2 x float> %b to <2 x half>117 ret <2 x half> %c118}119 120define half @test4-fast(float %a) {121; CHECK-LABEL: @test4-fast(122; CHECK-NEXT: [[TMP1:%.*]] = fptrunc fast float [[A:%.*]] to half123; CHECK-NEXT: [[C:%.*]] = fneg fast half [[TMP1]]124; CHECK-NEXT: ret half [[C]]125;126 %b = fsub fast float -0.0, %a127 %c = fptrunc fast float %b to half128 ret half %c129}130 131define half @test4-mixed-fast-1(float %a) {132; CHECK-LABEL: @test4-mixed-fast-1(133; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half134; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]135; CHECK-NEXT: ret half [[C]]136;137 %b = fsub float -0.0, %a138 %c = fptrunc fast float %b to half139 ret half %c140}141 142define half @test4-mixed-fast-2(float %a) {143; CHECK-LABEL: @test4-mixed-fast-2(144; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half145; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]146; CHECK-NEXT: ret half [[C]]147;148 %b = fsub fast float -0.0, %a149 %c = fptrunc float %b to half150 ret half %c151}152 153define half @test4_unary_fneg-fast(float %a) {154; CHECK-LABEL: @test4_unary_fneg-fast(155; CHECK-NEXT: [[TMP1:%.*]] = fptrunc fast float [[A:%.*]] to half156; CHECK-NEXT: [[C:%.*]] = fneg fast half [[TMP1]]157; CHECK-NEXT: ret half [[C]]158;159 %b = fneg fast float %a160 %c = fptrunc fast float %b to half161 ret half %c162}163 164define half @test4_unary_fneg-mixed-fast-1(float %a) {165; CHECK-LABEL: @test4_unary_fneg-mixed-fast-1(166; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half167; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]168; CHECK-NEXT: ret half [[C]]169;170 %b = fneg float %a171 %c = fptrunc fast float %b to half172 ret half %c173}174 175define half @test4_unary_fneg-mixed-fast-2(float %a) {176; CHECK-LABEL: @test4_unary_fneg-mixed-fast-2(177; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[A:%.*]] to half178; CHECK-NEXT: [[C:%.*]] = fneg half [[TMP1]]179; CHECK-NEXT: ret half [[C]]180;181 %b = fneg fast float %a182 %c = fptrunc float %b to half183 ret half %c184}185 186define <2 x half> @test4_unary_fneg-vec-fast(<2 x float> %a) {187; CHECK-LABEL: @test4_unary_fneg-vec-fast(188; CHECK-NEXT: [[TMP1:%.*]] = fptrunc fast <2 x float> [[A:%.*]] to <2 x half>189; CHECK-NEXT: [[C:%.*]] = fneg fast <2 x half> [[TMP1]]190; CHECK-NEXT: ret <2 x half> [[C]]191;192 %b = fneg fast <2 x float> %a193 %c = fptrunc fast <2 x float> %b to <2 x half>194 ret <2 x half> %c195}196 197define <2 x half> @test4_unary_fneg-vec-mixed-fast-1(<2 x float> %a) {198; CHECK-LABEL: @test4_unary_fneg-vec-mixed-fast-1(199; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x float> [[A:%.*]] to <2 x half>200; CHECK-NEXT: [[C:%.*]] = fneg <2 x half> [[TMP1]]201; CHECK-NEXT: ret <2 x half> [[C]]202;203 %b = fneg <2 x float> %a204 %c = fptrunc fast <2 x float> %b to <2 x half>205 ret <2 x half> %c206}207 208define <2 x half> @test4_unary_fneg-vec-mixed-fast-2(<2 x float> %a) {209; CHECK-LABEL: @test4_unary_fneg-vec-mixed-fast-2(210; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x float> [[A:%.*]] to <2 x half>211; CHECK-NEXT: [[C:%.*]] = fneg <2 x half> [[TMP1]]212; CHECK-NEXT: ret <2 x half> [[C]]213;214 %b = fneg fast <2 x float> %a215 %c = fptrunc <2 x float> %b to <2 x half>216 ret <2 x half> %c217}218 219define half @test5(float %a, float %b, float %c) {220; CHECK-LABEL: @test5(221; CHECK-NEXT: [[D:%.*]] = fcmp ogt float [[A:%.*]], [[B:%.*]]222; CHECK-NEXT: [[E:%.*]] = select i1 [[D]], float [[C:%.*]], float 1.000000e+00223; CHECK-NEXT: [[F:%.*]] = fptrunc float [[E]] to half224; CHECK-NEXT: ret half [[F]]225;226 %d = fcmp ogt float %a, %b227 %e = select i1 %d, float %c, float 1.0228 %f = fptrunc float %e to half229 ret half %f230}231 232declare float @llvm.fabs.f32(float) nounwind readonly233 234define <1 x float> @test6(<1 x double> %V) {235; CHECK-LABEL: @test6(236; CHECK-NEXT: [[FREM:%.*]] = frem <1 x double> [[V:%.*]], [[V]]237; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc <1 x double> [[FREM]] to <1 x float>238; CHECK-NEXT: ret <1 x float> [[TRUNC]]239;240 %frem = frem <1 x double> %V, %V241 %trunc = fptrunc <1 x double> %frem to <1 x float>242 ret <1 x float> %trunc243}244 245define float @test7(double %V) {246; CHECK-LABEL: @test7(247; CHECK-NEXT: [[FREM:%.*]] = frem double [[V:%.*]], 1.000000e+00248; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc double [[FREM]] to float249; CHECK-NEXT: ret float [[TRUNC]]250;251 %frem = frem double %V, 1.000000e+00252 %trunc = fptrunc double %frem to float253 ret float %trunc254}255 256define float @test8(float %V) {257; CHECK-LABEL: @test8(258; CHECK-NEXT: [[FEXT:%.*]] = fpext float [[V:%.*]] to double259; CHECK-NEXT: [[FREM:%.*]] = frem double [[FEXT]], 1.000000e-01260; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc double [[FREM]] to float261; CHECK-NEXT: ret float [[TRUNC]]262;263 %fext = fpext float %V to double264 %frem = frem double %fext, 1.000000e-01265 %trunc = fptrunc double %frem to float266 ret float %trunc267}268 269define half @test_fptrunc_fptrunc(double %V) {270; CHECK-LABEL: @test_fptrunc_fptrunc(271; CHECK-NEXT: [[T1:%.*]] = fptrunc double [[V:%.*]] to float272; CHECK-NEXT: [[T2:%.*]] = fptrunc float [[T1]] to half273; CHECK-NEXT: ret half [[T2]]274;275 %t1 = fptrunc double %V to float276 %t2 = fptrunc float %t1 to half277 ret half %t2278}279 280define half @sint_to_fptrunc(i32 %x) {281; CHECK-LABEL: @sint_to_fptrunc(282; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[X:%.*]] to float283; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half284; CHECK-NEXT: ret half [[R]]285;286 %f = sitofp i32 %x to float287 %r = fptrunc float %f to half288 ret half %r289}290 291define half @masked_sint_to_fptrunc1(i32 %x) {292; CHECK-LABEL: @masked_sint_to_fptrunc1(293; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215294; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half295; CHECK-NEXT: ret half [[R]]296;297 %m = and i32 %x, 16777215298 %f = sitofp i32 %m to float299 %r = fptrunc float %f to half300 ret half %r301}302 303define half @masked_sint_to_fptrunc2(i32 %x) {304; CHECK-LABEL: @masked_sint_to_fptrunc2(305; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8306; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half307; CHECK-NEXT: ret half [[R]]308;309 %m = lshr i32 %x, 8310 %f = sitofp i32 %m to float311 %r = fptrunc float %f to half312 ret half %r313}314 315define half @masked_sint_to_fptrunc3(i32 %x) {316; CHECK-LABEL: @masked_sint_to_fptrunc3(317; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7318; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float319; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half320; CHECK-NEXT: ret half [[R]]321;322 %m = lshr i32 %x, 7323 %f = sitofp i32 %m to float324 %r = fptrunc float %f to half325 ret half %r326}327 328define double @sint_to_fpext(i32 %x) {329; CHECK-LABEL: @sint_to_fpext(330; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[X:%.*]] to float331; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double332; CHECK-NEXT: ret double [[R]]333;334 %f = sitofp i32 %x to float335 %r = fpext float %f to double336 ret double %r337}338 339define double @masked_sint_to_fpext1(i32 %x) {340; CHECK-LABEL: @masked_sint_to_fpext1(341; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215342; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double343; CHECK-NEXT: ret double [[R]]344;345 %m = and i32 %x, 16777215346 %f = sitofp i32 %m to float347 %r = fpext float %f to double348 ret double %r349}350 351define double @masked_sint_to_fpext2(i32 %x) {352; CHECK-LABEL: @masked_sint_to_fpext2(353; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8354; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double355; CHECK-NEXT: ret double [[R]]356;357 %m = lshr i32 %x, 8358 %f = sitofp i32 %m to float359 %r = fpext float %f to double360 ret double %r361}362 363define double @masked_sint_to_fpext3(i32 %x) {364; CHECK-LABEL: @masked_sint_to_fpext3(365; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7366; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float367; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double368; CHECK-NEXT: ret double [[R]]369;370 %m = lshr i32 %x, 7371 %f = sitofp i32 %m to float372 %r = fpext float %f to double373 ret double %r374}375 376define half @uint_to_fptrunc(i32 %x) {377; CHECK-LABEL: @uint_to_fptrunc(378; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[X:%.*]] to float379; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half380; CHECK-NEXT: ret half [[R]]381;382 %f = uitofp i32 %x to float383 %r = fptrunc float %f to half384 ret half %r385}386 387define half @masked_uint_to_fptrunc1(i32 %x) {388; CHECK-LABEL: @masked_uint_to_fptrunc1(389; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215390; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half391; CHECK-NEXT: ret half [[R]]392;393 %m = and i32 %x, 16777215394 %f = uitofp i32 %m to float395 %r = fptrunc float %f to half396 ret half %r397}398 399define half @masked_uint_to_fptrunc2(i32 %x) {400; CHECK-LABEL: @masked_uint_to_fptrunc2(401; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8402; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half403; CHECK-NEXT: ret half [[R]]404;405 %m = lshr i32 %x, 8406 %f = uitofp i32 %m to float407 %r = fptrunc float %f to half408 ret half %r409}410 411define half @masked_uint_to_fptrunc3(i32 %x) {412; CHECK-LABEL: @masked_uint_to_fptrunc3(413; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7414; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float415; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half416; CHECK-NEXT: ret half [[R]]417;418 %m = lshr i32 %x, 7419 %f = uitofp i32 %m to float420 %r = fptrunc float %f to half421 ret half %r422}423 424define double @uint_to_fpext(i32 %x) {425; CHECK-LABEL: @uint_to_fpext(426; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[X:%.*]] to float427; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double428; CHECK-NEXT: ret double [[R]]429;430 %f = uitofp i32 %x to float431 %r = fpext float %f to double432 ret double %r433}434 435define double @masked_uint_to_fpext1(i32 %x) {436; CHECK-LABEL: @masked_uint_to_fpext1(437; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215438; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double439; CHECK-NEXT: ret double [[R]]440;441 %m = and i32 %x, 16777215442 %f = uitofp i32 %m to float443 %r = fpext float %f to double444 ret double %r445}446 447define double @masked_uint_to_fpext2(i32 %x) {448; CHECK-LABEL: @masked_uint_to_fpext2(449; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8450; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double451; CHECK-NEXT: ret double [[R]]452;453 %m = lshr i32 %x, 8454 %f = uitofp i32 %m to float455 %r = fpext float %f to double456 ret double %r457}458 459define double @masked_uint_to_fpext3(i32 %x) {460; CHECK-LABEL: @masked_uint_to_fpext3(461; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7462; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float463; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double464; CHECK-NEXT: ret double [[R]]465;466 %m = lshr i32 %x, 7467 %f = uitofp i32 %m to float468 %r = fpext float %f to double469 ret double %r470}471 472define i32 @fptosi_nonnorm(float nofpclass(norm) %x) {473; CHECK-LABEL: @fptosi_nonnorm(474; CHECK-NEXT: ret i32 0475;476 %ret = fptosi float %x to i32477 ret i32 %ret478}479 480define i32 @fptoui_nonnorm(float nofpclass(pnorm) %x) {481; CHECK-LABEL: @fptoui_nonnorm(482; CHECK-NEXT: ret i32 0483;484 %ret = fptoui float %x to i32485 ret i32 %ret486}487 488define i32 @fptosi_nonnnorm(float nofpclass(nnorm) %x) {489; CHECK-LABEL: @fptosi_nonnnorm(490; CHECK-NEXT: [[RET:%.*]] = fptosi float [[X:%.*]] to i32491; CHECK-NEXT: ret i32 [[RET]]492;493 %ret = fptosi float %x to i32494 ret i32 %ret495}496 497define i32 @fptoui_nonnnorm(float nofpclass(nnorm) %x) {498; CHECK-LABEL: @fptoui_nonnnorm(499; CHECK-NEXT: [[RET:%.*]] = fptoui float [[X:%.*]] to i32500; CHECK-NEXT: ret i32 [[RET]]501;502 %ret = fptoui float %x to i32503 ret i32 %ret504}505 506define i32 @fptosi_nonnorm_copysign(float %x) {507; CHECK-LABEL: @fptosi_nonnorm_copysign(508; CHECK-NEXT: ret i32 0509;510 %val = call float @llvm.copysign.f32(float 0.0, float %x)511 %ret = fptosi float %val to i32512 ret i32 %ret513}514 515define <2 x i32> @fptosi_nonnorm_copysign_vec(<2 x float> %x) {516; CHECK-LABEL: @fptosi_nonnorm_copysign_vec(517; CHECK-NEXT: ret <2 x i32> zeroinitializer518;519 %val = call <2 x float> @llvm.copysign.v2f32(<2 x float> zeroinitializer, <2 x float> %x)520 %ret = fptosi <2 x float> %val to <2 x i32>521 ret <2 x i32> %ret522}523 524define i32 @fptosi_nonnorm_fmul(float %x) {525; CHECK-LABEL: @fptosi_nonnorm_fmul(526; CHECK-NEXT: [[SEL:%.*]] = fmul float [[X:%.*]], 0.000000e+00527; CHECK-NEXT: [[RET:%.*]] = fptosi float [[SEL]] to i32528; CHECK-NEXT: ret i32 [[RET]]529;530 %sel = fmul float %x, 0.000000e+00531 %ret = fptosi float %sel to i32532 ret i32 %ret533}534 535define i32 @fptosi_select(i1 %cond) {536; CHECK-LABEL: @fptosi_select(537; CHECK-NEXT: [[RET:%.*]] = select i1 [[COND:%.*]], i32 1, i32 -1538; CHECK-NEXT: ret i32 [[RET]]539;540 %sel = select i1 %cond, float 1.0, float -1.0541 %ret = fptosi float %sel to i32542 ret i32 %ret543}544 545define i32 @mul_pos_zero_convert(i32 %a) {546; CHECK-LABEL: @mul_pos_zero_convert(547; CHECK-NEXT: entry:548; CHECK-NEXT: ret i32 0549;550entry:551 %fp = sitofp i32 %a to float552 %ret = fmul float %fp, 0.000000e+00553 %conv = fptosi float %ret to i32554 ret i32 %conv555}556