Skip to content

Commit 2811085

Browse files
committed
InstCombine: Add some additional is.fpclass tests
Add some tests to generalize the clearing of known bits using computeKnownFPClass instead of isKnownNeverNaN/isKnownNeverInfinity.
1 parent 94adb39 commit 2811085

File tree

1 file changed

+326
-0
lines changed

1 file changed

+326
-0
lines changed

llvm/test/Transforms/InstCombine/is_fpclass.ll

Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,334 @@ define <2 x i1> @test_class_fneg_fabs_posinf_negnormal_possubnormal_negzero_nan_
24362436
ret <2 x i1> %class
24372437
}
24382438

2439+
define i1 @test_class_is_zero_nozero_src(float nofpclass(zero) %arg) {
2440+
; CHECK-LABEL: @test_class_is_zero_nozero_src(
2441+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0.000000e+00
2442+
; CHECK-NEXT: ret i1 [[CLASS]]
2443+
;
2444+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 96)
2445+
ret i1 %class
2446+
}
2447+
2448+
define i1 @test_class_is_zero_noposzero_src(float nofpclass(pzero) %arg) {
2449+
; CHECK-LABEL: @test_class_is_zero_noposzero_src(
2450+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0.000000e+00
2451+
; CHECK-NEXT: ret i1 [[CLASS]]
2452+
;
2453+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 96)
2454+
ret i1 %class
2455+
}
2456+
2457+
define i1 @test_class_is_zero_nonegzero_src(float nofpclass(nzero) %arg) {
2458+
; CHECK-LABEL: @test_class_is_zero_nonegzero_src(
2459+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0.000000e+00
2460+
; CHECK-NEXT: ret i1 [[CLASS]]
2461+
;
2462+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 96)
2463+
ret i1 %class
2464+
}
2465+
2466+
define i1 @test_class_is_pzero_nozero_src(float nofpclass(zero) %arg) {
2467+
; CHECK-LABEL: @test_class_is_pzero_nozero_src(
2468+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 64)
2469+
; CHECK-NEXT: ret i1 [[CLASS]]
2470+
;
2471+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 64)
2472+
ret i1 %class
2473+
}
2474+
2475+
define i1 @test_class_is_pzero_nopzero_src(float nofpclass(pzero) %arg) {
2476+
; CHECK-LABEL: @test_class_is_pzero_nopzero_src(
2477+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 64)
2478+
; CHECK-NEXT: ret i1 [[CLASS]]
2479+
;
2480+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 64)
2481+
ret i1 %class
2482+
}
2483+
2484+
define i1 @test_class_is_pzero_nonzero_src(float nofpclass(nzero) %arg) {
2485+
; CHECK-LABEL: @test_class_is_pzero_nonzero_src(
2486+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 64)
2487+
; CHECK-NEXT: ret i1 [[CLASS]]
2488+
;
2489+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 64)
2490+
ret i1 %class
2491+
}
2492+
2493+
define i1 @test_class_is_nzero_nozero_src(float nofpclass(zero) %arg) {
2494+
; CHECK-LABEL: @test_class_is_nzero_nozero_src(
2495+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 32)
2496+
; CHECK-NEXT: ret i1 [[CLASS]]
2497+
;
2498+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 32)
2499+
ret i1 %class
2500+
}
2501+
2502+
define i1 @test_class_is_nzero_nopzero_src(float nofpclass(pzero) %arg) {
2503+
; CHECK-LABEL: @test_class_is_nzero_nopzero_src(
2504+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 32)
2505+
; CHECK-NEXT: ret i1 [[CLASS]]
2506+
;
2507+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 32)
2508+
ret i1 %class
2509+
}
2510+
2511+
define i1 @test_class_is_nzero_nonzero_src(float nofpclass(nzero) %arg) {
2512+
; CHECK-LABEL: @test_class_is_nzero_nonzero_src(
2513+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 32)
2514+
; CHECK-NEXT: ret i1 [[CLASS]]
2515+
;
2516+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 32)
2517+
ret i1 %class
2518+
}
2519+
2520+
define i1 @test_class_is_normal_or_zero_nozero_src(float nofpclass(zero) %arg) {
2521+
; CHECK-LABEL: @test_class_is_normal_or_zero_nozero_src(
2522+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 360)
2523+
; CHECK-NEXT: ret i1 [[CLASS]]
2524+
;
2525+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 360)
2526+
ret i1 %class
2527+
}
2528+
2529+
define i1 @test_class_is_inf_or_nan_nozero_src(float nofpclass(zero) %arg) {
2530+
; CHECK-LABEL: @test_class_is_inf_or_nan_nozero_src(
2531+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 519)
2532+
; CHECK-NEXT: ret i1 [[CLASS]]
2533+
;
2534+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 519)
2535+
ret i1 %class
2536+
}
2537+
2538+
define i1 @test_class_is_inf_or_nan_noinf_src(float nofpclass(inf) %arg) {
2539+
; CHECK-LABEL: @test_class_is_inf_or_nan_noinf_src(
2540+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno float [[ARG:%.*]], 0.000000e+00
2541+
; CHECK-NEXT: ret i1 [[CLASS]]
2542+
;
2543+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 519)
2544+
ret i1 %class
2545+
}
2546+
2547+
define i1 @test_class_is_inf_or_nan_nonan_src(float nofpclass(nan) %arg) {
2548+
; CHECK-LABEL: @test_class_is_inf_or_nan_nonan_src(
2549+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 516)
2550+
; CHECK-NEXT: ret i1 [[CLASS]]
2551+
;
2552+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 519)
2553+
ret i1 %class
2554+
}
2555+
2556+
define i1 @test_class_is_normal_or_subnormal_noinf_src(float nofpclass(inf) %arg) {
2557+
; CHECK-LABEL: @test_class_is_normal_or_subnormal_noinf_src(
2558+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 408)
2559+
; CHECK-NEXT: ret i1 [[CLASS]]
2560+
;
2561+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 408)
2562+
ret i1 %class
2563+
}
2564+
2565+
define i1 @test_class_is_neginf_or_nopinf_src(float nofpclass(pinf) %arg) {
2566+
; CHECK-LABEL: @test_class_is_neginf_or_nopinf_src(
2567+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0xFFF0000000000000
2568+
; CHECK-NEXT: ret i1 [[CLASS]]
2569+
;
2570+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 4)
2571+
ret i1 %class
2572+
}
2573+
2574+
define i1 @test_class_is_neginf_noninf_src(float nofpclass(ninf) %arg) {
2575+
; CHECK-LABEL: @test_class_is_neginf_noninf_src(
2576+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0xFFF0000000000000
2577+
; CHECK-NEXT: ret i1 [[CLASS]]
2578+
;
2579+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 4)
2580+
ret i1 %class
2581+
}
2582+
2583+
define i1 @test_class_is_neginf_noinf_src(float nofpclass(inf) %arg) {
2584+
; CHECK-LABEL: @test_class_is_neginf_noinf_src(
2585+
; CHECK-NEXT: ret i1 false
2586+
;
2587+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 4)
2588+
ret i1 %class
2589+
}
2590+
2591+
define i1 @test_class_is_posinf_noninf_src(float nofpclass(ninf) %arg) {
2592+
; CHECK-LABEL: @test_class_is_posinf_noninf_src(
2593+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0x7FF0000000000000
2594+
; CHECK-NEXT: ret i1 [[CLASS]]
2595+
;
2596+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 512)
2597+
ret i1 %class
2598+
}
2599+
2600+
define i1 @test_class_is_posinf_nopinf_src(float nofpclass(pinf) %arg) {
2601+
; CHECK-LABEL: @test_class_is_posinf_nopinf_src(
2602+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq float [[ARG:%.*]], 0x7FF0000000000000
2603+
; CHECK-NEXT: ret i1 [[CLASS]]
2604+
;
2605+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 512)
2606+
ret i1 %class
2607+
}
2608+
2609+
define i1 @test_class_is_posinf_noinf_src(float nofpclass(inf) %arg) {
2610+
; CHECK-LABEL: @test_class_is_posinf_noinf_src(
2611+
; CHECK-NEXT: ret i1 false
2612+
;
2613+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 512)
2614+
ret i1 %class
2615+
}
2616+
2617+
define i1 @test_class_is_subnormal_nosub_src(float nofpclass(sub) %arg) {
2618+
; CHECK-LABEL: @test_class_is_subnormal_nosub_src(
2619+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 144)
2620+
; CHECK-NEXT: ret i1 [[CLASS]]
2621+
;
2622+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 144)
2623+
ret i1 %class
2624+
}
2625+
2626+
define i1 @test_class_is_subnormal_nonsub_src(float nofpclass(nsub) %arg) {
2627+
; CHECK-LABEL: @test_class_is_subnormal_nonsub_src(
2628+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 144)
2629+
; CHECK-NEXT: ret i1 [[CLASS]]
2630+
;
2631+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 144)
2632+
ret i1 %class
2633+
}
2634+
2635+
define i1 @test_class_is_not_subnormal_nosub_src(float nofpclass(sub) %arg) {
2636+
; CHECK-LABEL: @test_class_is_not_subnormal_nosub_src(
2637+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 879)
2638+
; CHECK-NEXT: ret i1 [[CLASS]]
2639+
;
2640+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 879)
2641+
ret i1 %class
2642+
}
2643+
2644+
define i1 @test_class_is_not_negsubnormal_nosub_src(float nofpclass(sub) %arg) {
2645+
; CHECK-LABEL: @test_class_is_not_negsubnormal_nosub_src(
2646+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 1007)
2647+
; CHECK-NEXT: ret i1 [[CLASS]]
2648+
;
2649+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 1007)
2650+
ret i1 %class
2651+
}
2652+
2653+
define i1 @test_class_is_not_negsubnormal_nonegsub_src(float nofpclass(nsub) %arg) {
2654+
; CHECK-LABEL: @test_class_is_not_negsubnormal_nonegsub_src(
2655+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 1007)
2656+
; CHECK-NEXT: ret i1 [[CLASS]]
2657+
;
2658+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 1007)
2659+
ret i1 %class
2660+
}
2661+
2662+
define i1 @test_class_is_nnormal_nonorm_src(float nofpclass(norm) %arg) {
2663+
; CHECK-LABEL: @test_class_is_nnormal_nonorm_src(
2664+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 264)
2665+
; CHECK-NEXT: ret i1 [[CLASS]]
2666+
;
2667+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 264)
2668+
ret i1 %class
2669+
}
2670+
2671+
define i1 @test_class_is_not_nnormal_nonorm_src(float nofpclass(norm) %arg) {
2672+
; CHECK-LABEL: @test_class_is_not_nnormal_nonorm_src(
2673+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 759)
2674+
; CHECK-NEXT: ret i1 [[CLASS]]
2675+
;
2676+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 759)
2677+
ret i1 %class
2678+
}
2679+
2680+
define i1 @test_class_is_not_nnormal_onlynorm_src(float nofpclass(nan inf zero sub) %arg) {
2681+
; CHECK-LABEL: @test_class_is_not_nnormal_onlynorm_src(
2682+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 240)
2683+
; CHECK-NEXT: ret i1 [[CLASS]]
2684+
;
2685+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 759)
2686+
ret i1 %class
2687+
}
2688+
2689+
define i1 @test_class_is_nnormal_onlynorm_src(float nofpclass(nan inf zero sub) %arg) {
2690+
; CHECK-LABEL: @test_class_is_nnormal_onlynorm_src(
2691+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 264)
2692+
; CHECK-NEXT: ret i1 [[CLASS]]
2693+
;
2694+
%class = call i1 @llvm.is.fpclass.f32(float %arg, i32 264)
2695+
ret i1 %class
2696+
}
2697+
2698+
; Make sure assume works
2699+
define i1 @test_class_is_normal_assume_normal(float %x) {
2700+
; CHECK-LABEL: @test_class_is_normal_assume_normal(
2701+
; CHECK-NEXT: [[ASSUMED_IS_NORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 264)
2702+
; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMED_IS_NORMAL]])
2703+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 264)
2704+
; CHECK-NEXT: ret i1 [[CLASS]]
2705+
;
2706+
%assumed.is.normal = call i1 @llvm.is.fpclass.f32(float %x, i32 264)
2707+
call void @llvm.assume(i1 %assumed.is.normal)
2708+
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 264)
2709+
ret i1 %class
2710+
}
2711+
2712+
define i1 @test_class_is_normal_assume_not_normal(float %x) {
2713+
; CHECK-LABEL: @test_class_is_normal_assume_not_normal(
2714+
; CHECK-NEXT: [[ASSUMED_IS_NORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X:%.*]], i32 264)
2715+
; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMED_IS_NORMAL]])
2716+
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f32(float [[X]], i32 759)
2717+
; CHECK-NEXT: ret i1 [[CLASS]]
2718+
;
2719+
%assumed.is.normal = call i1 @llvm.is.fpclass.f32(float %x, i32 264)
2720+
call void @llvm.assume(i1 %assumed.is.normal)
2721+
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 759)
2722+
ret i1 %class
2723+
}
2724+
2725+
define i1 @test_class_is_nan_assume_ord(float %x) {
2726+
; CHECK-LABEL: @test_class_is_nan_assume_ord(
2727+
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
2728+
; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
2729+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno float [[X]], 0.000000e+00
2730+
; CHECK-NEXT: ret i1 [[CLASS]]
2731+
;
2732+
%ord = fcmp ord float %x, 0.0
2733+
call void @llvm.assume(i1 %ord)
2734+
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 3)
2735+
ret i1 %class
2736+
}
2737+
2738+
define i1 @test_class_is_nan_assume_uno(float %x) {
2739+
; CHECK-LABEL: @test_class_is_nan_assume_uno(
2740+
; CHECK-NEXT: [[ORD:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
2741+
; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
2742+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno float [[X]], 0.000000e+00
2743+
; CHECK-NEXT: ret i1 [[CLASS]]
2744+
;
2745+
%ord = fcmp uno float %x, 0.0
2746+
call void @llvm.assume(i1 %ord)
2747+
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 3)
2748+
ret i1 %class
2749+
}
2750+
2751+
define i1 @test_class_is_nan_assume_not_eq_pinf(float %x) {
2752+
; CHECK-LABEL: @test_class_is_nan_assume_not_eq_pinf(
2753+
; CHECK-NEXT: [[ORD:%.*]] = fcmp oeq float [[X:%.*]], 0x7FF0000000000000
2754+
; CHECK-NEXT: call void @llvm.assume(i1 [[ORD]])
2755+
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno float [[X]], 0.000000e+00
2756+
; CHECK-NEXT: ret i1 [[CLASS]]
2757+
;
2758+
%ord = fcmp oeq float %x, 0x7FF0000000000000
2759+
call void @llvm.assume(i1 %ord)
2760+
%class = call i1 @llvm.is.fpclass.f32(float %x, i32 3)
2761+
ret i1 %class
2762+
}
2763+
24392764
declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
24402765
declare i1 @llvm.is.fpclass.f64(double, i32 immarg)
24412766
declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg)
24422767
declare float @llvm.fabs.f32(float)
24432768
declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
2769+
declare void @llvm.assume(i1 noundef)

0 commit comments

Comments
 (0)