|
1 | 1 | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
2 | 2 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
3 | 3 |
|
| 4 | +declare float @llvm.ldexp.f32.i32(float, i32) |
| 5 | +declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) |
4 | 6 | declare void @use(float)
|
5 | 7 |
|
6 | 8 | define float @fneg_fneg(float %a) {
|
@@ -829,3 +831,161 @@ define float @select_fneg_use3(float %x, float %y, i1 %b) {
|
829 | 831 | %r = fneg float %s
|
830 | 832 | ret float %r
|
831 | 833 | }
|
| 834 | + |
| 835 | +define float @fneg_ldexp(float %x, i32 %n) { |
| 836 | +; CHECK-LABEL: @fneg_ldexp( |
| 837 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 838 | +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] |
| 839 | +; CHECK-NEXT: ret float [[NEG]] |
| 840 | +; |
| 841 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 842 | + %neg = fneg float %ldexp |
| 843 | + ret float %neg |
| 844 | +} |
| 845 | + |
| 846 | +define float @fsub_fneg_ldexp(float %x, i32 %n) { |
| 847 | +; CHECK-LABEL: @fsub_fneg_ldexp( |
| 848 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 849 | +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] |
| 850 | +; CHECK-NEXT: ret float [[NEG]] |
| 851 | +; |
| 852 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 853 | + %neg = fsub float -0.0, %ldexp |
| 854 | + ret float %neg |
| 855 | +} |
| 856 | + |
| 857 | +define float @fsub_fneg_ldexp_nsz(float %x, i32 %n) { |
| 858 | +; CHECK-LABEL: @fsub_fneg_ldexp_nsz( |
| 859 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 860 | +; CHECK-NEXT: [[NEG:%.*]] = fneg nsz float [[LDEXP]] |
| 861 | +; CHECK-NEXT: ret float [[NEG]] |
| 862 | +; |
| 863 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 864 | + %neg = fsub nsz float -0.0, %ldexp |
| 865 | + ret float %neg |
| 866 | +} |
| 867 | + |
| 868 | +define float @fsub_fneg_ldexp_p0_nsz(float %x, i32 %n) { |
| 869 | +; CHECK-LABEL: @fsub_fneg_ldexp_p0_nsz( |
| 870 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 871 | +; CHECK-NEXT: [[NEG:%.*]] = fneg nsz float [[LDEXP]] |
| 872 | +; CHECK-NEXT: ret float [[NEG]] |
| 873 | +; |
| 874 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 875 | + %neg = fsub nsz float 0.0, %ldexp |
| 876 | + ret float %neg |
| 877 | +} |
| 878 | + |
| 879 | +define float @fsub_fneg_ldexp_p0(float %x, i32 %n) { |
| 880 | +; CHECK-LABEL: @fsub_fneg_ldexp_p0( |
| 881 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 882 | +; CHECK-NEXT: [[NEG:%.*]] = fsub float 0.000000e+00, [[LDEXP]] |
| 883 | +; CHECK-NEXT: ret float [[NEG]] |
| 884 | +; |
| 885 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 886 | + %neg = fsub float 0.0, %ldexp |
| 887 | + ret float %neg |
| 888 | +} |
| 889 | + |
| 890 | +define <2 x float> @fneg_ldexp_vector(<2 x float> %x, <2 x i32> %n) { |
| 891 | +; CHECK-LABEL: @fneg_ldexp_vector( |
| 892 | +; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X:%.*]], <2 x i32> [[N:%.*]]) |
| 893 | +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[LDEXP]] |
| 894 | +; CHECK-NEXT: ret <2 x float> [[NEG]] |
| 895 | +; |
| 896 | + %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %n) |
| 897 | + %neg = fneg <2 x float> %ldexp |
| 898 | + ret <2 x float> %neg |
| 899 | +} |
| 900 | + |
| 901 | +define float @fneg_ldexp_multiuse(float %x, i32 %n, ptr %ptr) { |
| 902 | +; CHECK-LABEL: @fneg_ldexp_multiuse( |
| 903 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 904 | +; CHECK-NEXT: store float [[LDEXP]], ptr [[PTR:%.*]], align 4 |
| 905 | +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] |
| 906 | +; CHECK-NEXT: ret float [[NEG]] |
| 907 | +; |
| 908 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 909 | + store float %ldexp, ptr %ptr |
| 910 | + %neg = fneg float %ldexp |
| 911 | + ret float %neg |
| 912 | +} |
| 913 | + |
| 914 | +define float @fneg_ldexp_fmf_ldexp(float %x, i32 %n) { |
| 915 | +; CHECK-LABEL: @fneg_ldexp_fmf_ldexp( |
| 916 | +; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 917 | +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] |
| 918 | +; CHECK-NEXT: ret float [[NEG]] |
| 919 | +; |
| 920 | + %ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 921 | + %neg = fneg float %ldexp |
| 922 | + ret float %neg |
| 923 | +} |
| 924 | + |
| 925 | +define float @fneg_ldexp_fmf_neg(float %x, i32 %n) { |
| 926 | +; CHECK-LABEL: @fneg_ldexp_fmf_neg( |
| 927 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 928 | +; CHECK-NEXT: [[NEG:%.*]] = fneg nnan float [[LDEXP]] |
| 929 | +; CHECK-NEXT: ret float [[NEG]] |
| 930 | +; |
| 931 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 932 | + %neg = fneg nnan float %ldexp |
| 933 | + ret float %neg |
| 934 | +} |
| 935 | + |
| 936 | +define float @fneg_ldexp_fmf(float %x, i32 %n) { |
| 937 | +; CHECK-LABEL: @fneg_ldexp_fmf( |
| 938 | +; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 939 | +; CHECK-NEXT: [[NEG:%.*]] = fneg nnan float [[LDEXP]] |
| 940 | +; CHECK-NEXT: ret float [[NEG]] |
| 941 | +; |
| 942 | + %ldexp = call ninf float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 943 | + %neg = fneg nnan float %ldexp |
| 944 | + ret float %neg |
| 945 | +} |
| 946 | + |
| 947 | +define float @fneg_ldexp_contract0(float %x, i32 %n) { |
| 948 | +; CHECK-LABEL: @fneg_ldexp_contract0( |
| 949 | +; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 950 | +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] |
| 951 | +; CHECK-NEXT: ret float [[NEG]] |
| 952 | +; |
| 953 | + %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 954 | + %neg = fneg float %ldexp |
| 955 | + ret float %neg |
| 956 | +} |
| 957 | + |
| 958 | +define float @fneg_ldexp_contract1(float %x, i32 %n) { |
| 959 | +; CHECK-LABEL: @fneg_ldexp_contract1( |
| 960 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 961 | +; CHECK-NEXT: [[NEG:%.*]] = fneg contract float [[LDEXP]] |
| 962 | +; CHECK-NEXT: ret float [[NEG]] |
| 963 | +; |
| 964 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 965 | + %neg = fneg contract float %ldexp |
| 966 | + ret float %neg |
| 967 | +} |
| 968 | + |
| 969 | +define float @fneg_ldexp_contract(float %x, i32 %n) { |
| 970 | +; CHECK-LABEL: @fneg_ldexp_contract( |
| 971 | +; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) |
| 972 | +; CHECK-NEXT: [[NEG:%.*]] = fneg contract float [[LDEXP]] |
| 973 | +; CHECK-NEXT: ret float [[NEG]] |
| 974 | +; |
| 975 | + %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n) |
| 976 | + %neg = fneg contract float %ldexp |
| 977 | + ret float %neg |
| 978 | +} |
| 979 | + |
| 980 | +define float @fneg_ldexp_metadata(float %x, i32 %n) { |
| 981 | +; CHECK-LABEL: @fneg_ldexp_metadata( |
| 982 | +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]), !arst !0 |
| 983 | +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] |
| 984 | +; CHECK-NEXT: ret float [[NEG]] |
| 985 | +; |
| 986 | + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n), !arst !0 |
| 987 | + %neg = fneg float %ldexp |
| 988 | + ret float %neg |
| 989 | +} |
| 990 | + |
| 991 | +!0 = !{} |
0 commit comments