diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll index 207e38f0953ed..d9047ad53e814 100644 --- a/llvm/test/Transforms/InstCombine/fneg.ll +++ b/llvm/test/Transforms/InstCombine/fneg.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s +declare float @llvm.ldexp.f32.i32(float, i32) +declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) declare void @use(float) define float @fneg_fneg(float %a) { @@ -829,3 +831,161 @@ define float @select_fneg_use3(float %x, float %y, i1 %b) { %r = fneg float %s ret float %r } + +define float @fneg_ldexp(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg float %ldexp + ret float %neg +} + +define float @fsub_fneg_ldexp(float %x, i32 %n) { +; CHECK-LABEL: @fsub_fneg_ldexp( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fsub float -0.0, %ldexp + ret float %neg +} + +define float @fsub_fneg_ldexp_nsz(float %x, i32 %n) { +; CHECK-LABEL: @fsub_fneg_ldexp_nsz( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg nsz float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fsub nsz float -0.0, %ldexp + ret float %neg +} + +define float @fsub_fneg_ldexp_p0_nsz(float %x, i32 %n) { +; CHECK-LABEL: @fsub_fneg_ldexp_p0_nsz( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg nsz float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fsub nsz float 0.0, %ldexp + ret float %neg +} + +define float @fsub_fneg_ldexp_p0(float %x, i32 %n) { +; CHECK-LABEL: @fsub_fneg_ldexp_p0( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fsub float 0.000000e+00, [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fsub float 0.0, %ldexp + ret float %neg +} + +define <2 x float> @fneg_ldexp_vector(<2 x float> %x, <2 x i32> %n) { +; CHECK-LABEL: @fneg_ldexp_vector( +; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X:%.*]], <2 x i32> [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg <2 x float> [[LDEXP]] +; CHECK-NEXT: ret <2 x float> [[NEG]] +; + %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %n) + %neg = fneg <2 x float> %ldexp + ret <2 x float> %neg +} + +define float @fneg_ldexp_multiuse(float %x, i32 %n, ptr %ptr) { +; CHECK-LABEL: @fneg_ldexp_multiuse( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: store float [[LDEXP]], ptr [[PTR:%.*]], align 4 +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + store float %ldexp, ptr %ptr + %neg = fneg float %ldexp + ret float %neg +} + +define float @fneg_ldexp_fmf_ldexp(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_fmf_ldexp( +; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg float %ldexp + ret float %neg +} + +define float @fneg_ldexp_fmf_neg(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_fmf_neg( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg nnan float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg nnan float %ldexp + ret float %neg +} + +define float @fneg_ldexp_fmf(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_fmf( +; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg nnan float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call ninf float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg nnan float %ldexp + ret float %neg +} + +define float @fneg_ldexp_contract0(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_contract0( +; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg float %ldexp + ret float %neg +} + +define float @fneg_ldexp_contract1(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_contract1( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg contract float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg contract float %ldexp + ret float %neg +} + +define float @fneg_ldexp_contract(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_contract( +; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[NEG:%.*]] = fneg contract float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 %n) + %neg = fneg contract float %ldexp + ret float %neg +} + +define float @fneg_ldexp_metadata(float %x, i32 %n) { +; CHECK-LABEL: @fneg_ldexp_metadata( +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X:%.*]], i32 [[N:%.*]]), !arst !0 +; CHECK-NEXT: [[NEG:%.*]] = fneg float [[LDEXP]] +; CHECK-NEXT: ret float [[NEG]] +; + %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %n), !arst !0 + %neg = fneg float %ldexp + ret float %neg +} + +!0 = !{}