| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s |
| |
| define float @ldexp_f32_undef_undef() { |
| ; CHECK-LABEL: @ldexp_f32_undef_undef( |
| ; CHECK-NEXT: ret float 0x7FF8000000000000 |
| ; |
| %call = call float @llvm.ldexp.f32.i32(float undef, i32 undef) |
| ret float %call |
| } |
| |
| define float @ldexp_f32_poison_undef() { |
| ; CHECK-LABEL: @ldexp_f32_poison_undef( |
| ; CHECK-NEXT: ret float poison |
| ; |
| %call = call float @llvm.ldexp.f32.i32(float poison, i32 undef) |
| ret float %call |
| } |
| |
| define float @ldexp_f32_undef_poison() { |
| ; CHECK-LABEL: @ldexp_f32_undef_poison( |
| ; CHECK-NEXT: ret float undef |
| ; |
| %call = call float @llvm.ldexp.f32.i32(float undef, i32 poison) |
| ret float %call |
| } |
| |
| define float @ldexp_f32_poison_poison() { |
| ; CHECK-LABEL: @ldexp_f32_poison_poison( |
| ; CHECK-NEXT: ret float poison |
| ; |
| %call = call float @llvm.ldexp.f32.i32(float poison, i32 poison) |
| ret float %call |
| } |
| |
| ; If the exponent is 0, it doesn't matter if the first argument is |
| ; constant or not. |
| define void @ldexp_f32_exp0(float %x) { |
| ; CHECK-LABEL: @ldexp_f32_exp0( |
| ; CHECK-NEXT: store volatile float [[X:%.*]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float [[X]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[ONE:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 1) |
| ; CHECK-NEXT: store volatile float [[ONE]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %zero = call float @llvm.ldexp.f32.i32(float %x, i32 0) |
| store volatile float %zero, ptr addrspace(1) undef |
| |
| %undef = call float @llvm.ldexp.f32.i32(float %x, i32 undef) |
| store volatile float %undef, ptr addrspace(1) undef |
| |
| %one = call float @llvm.ldexp.f32.i32(float %x, i32 1) |
| store volatile float %one, ptr addrspace(1) undef |
| ret void |
| } |
| |
| define void @ldexp_v2f32_exp0(<2 x float> %x) { |
| ; CHECK-LABEL: @ldexp_v2f32_exp0( |
| ; CHECK-NEXT: store volatile <2 x float> [[X:%.*]], ptr addrspace(1) undef, align 8 |
| ; CHECK-NEXT: store volatile <2 x float> [[X]], ptr addrspace(1) undef, align 8 |
| ; CHECK-NEXT: store volatile <2 x float> [[X]], ptr addrspace(1) undef, align 8 |
| ; CHECK-NEXT: ret void |
| ; |
| %part.undef0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 0, i32 undef>) |
| store volatile <2 x float> %part.undef0, ptr addrspace(1) undef |
| |
| %part.undef1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 undef, i32 0>) |
| store volatile <2 x float> %part.undef1, ptr addrspace(1) undef |
| |
| %zero = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> zeroinitializer) |
| store volatile <2 x float> %zero, ptr addrspace(1) undef |
| ret void |
| } |
| |
| ; Test variable exponent but zero or undef value. |
| define void @ldexp_f32_val0(i32 %y) { |
| ; CHECK-LABEL: @ldexp_f32_val0( |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %zero = call float @llvm.ldexp.f32.i32(float 0.0, i32 %y) |
| store volatile float %zero, ptr addrspace(1) undef |
| |
| %neg.zero = call float @llvm.ldexp.f32.i32(float -0.0, i32 %y) |
| store volatile float %neg.zero, ptr addrspace(1) undef |
| |
| %undef = call float @llvm.ldexp.f32.i32(float undef, i32 %y) |
| store volatile float %undef, ptr addrspace(1) undef |
| ret void |
| } |
| |
| define void @ldexp_f32_val_infinity(i32 %y) { |
| ; CHECK-LABEL: @ldexp_f32_val_infinity( |
| ; CHECK-NEXT: store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %inf = call float @llvm.ldexp.f32.i32(float 0x7ff0000000000000, i32 %y) |
| store volatile float %inf, ptr addrspace(1) undef |
| |
| %neg.inf = call float @llvm.ldexp.f32.i32(float 0xfff0000000000000, i32 %y) |
| store volatile float %neg.inf, ptr addrspace(1) undef |
| |
| %inf.zero = call float @llvm.ldexp.f32.i32(float 0x7ff0000000000000, i32 0) |
| store volatile float %inf.zero, ptr addrspace(1) undef |
| |
| %neg.inf.zero = call float @llvm.ldexp.f32.i32(float 0xfff0000000000000, i32 0) |
| store volatile float %neg.inf.zero, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| ; Signaling nan should be quieted. |
| ; Technically this depends on the ieee_mode in the mode register. |
| define void @ldexp_f32_val_nan(i32 %y) { |
| ; CHECK-LABEL: @ldexp_f32_val_nan( |
| ; CHECK-NEXT: store volatile float 0x7FF8001000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xFFF8000100000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x7FF8000020000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xFFFFFFFFE0000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %plus.qnan = call float @llvm.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y) |
| store volatile float %plus.qnan, ptr addrspace(1) undef |
| |
| %neg.qnan = call float @llvm.ldexp.f32.i32(float 0xfff0000100000000, i32 %y) |
| store volatile float %neg.qnan, ptr addrspace(1) undef |
| |
| %plus.snan = call float @llvm.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y) |
| store volatile float %plus.snan, ptr addrspace(1) undef |
| |
| %neg.snan = call float @llvm.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y) |
| store volatile float %neg.snan, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_f32_val_nan_strictfp_maytrap(i32 %y) #0 { |
| ; CHECK-LABEL: @ldexp_f32_val_nan_strictfp_maytrap( |
| ; CHECK-NEXT: [[PLUS_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0001000000000, i32 [[Y:%.*]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0:[0-9]+]] |
| ; CHECK-NEXT: store volatile float [[PLUS_QNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[NEG_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF0000100000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[NEG_QNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[PLUS_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[PLUS_SNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[NEG_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[NEG_SNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %plus.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %plus.qnan, ptr addrspace(1) undef |
| |
| %neg.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xfff0000100000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %neg.qnan, ptr addrspace(1) undef |
| |
| %plus.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %plus.snan, ptr addrspace(1) undef |
| |
| %neg.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %neg.snan, ptr addrspace(1) undef |
| |
| %undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %undef, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| |
| define void @ldexp_f32_val_nan_strictfp_strict(i32 %y) #0 { |
| ; CHECK-LABEL: @ldexp_f32_val_nan_strictfp_strict( |
| ; CHECK-NEXT: [[PLUS_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0001000000000, i32 [[Y:%.*]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[PLUS_QNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[NEG_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF0000100000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[NEG_QNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[PLUS_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[PLUS_SNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[NEG_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[NEG_SNAN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[UNDEF:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %plus.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 |
| store volatile float %plus.qnan, ptr addrspace(1) undef |
| |
| %neg.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xfff0000100000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 |
| store volatile float %neg.qnan, ptr addrspace(1) undef |
| |
| %plus.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 |
| store volatile float %plus.snan, ptr addrspace(1) undef |
| |
| %neg.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 |
| store volatile float %neg.snan, ptr addrspace(1) undef |
| |
| %undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 |
| store volatile float %undef, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_f32_0() { |
| ; CHECK-LABEL: @ldexp_f32_0( |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %zero = call float @llvm.ldexp.f32.i32(float 0.0, i32 0) |
| store volatile float %zero, ptr addrspace(1) undef |
| |
| %neg.zero = call float @llvm.ldexp.f32.i32(float -0.0, i32 0) |
| store volatile float %neg.zero, ptr addrspace(1) undef |
| |
| %one = call float @llvm.ldexp.f32.i32(float 0.0, i32 1) |
| store volatile float %one, ptr addrspace(1) undef |
| |
| %min.exp = call float @llvm.ldexp.f32.i32(float 0.0, i32 -126) |
| store volatile float %min.exp, ptr addrspace(1) undef |
| |
| %min.exp.sub1 = call float @llvm.ldexp.f32.i32(float 0.0, i32 -127) |
| store volatile float %min.exp.sub1, ptr addrspace(1) undef |
| |
| %max.exp = call float @llvm.ldexp.f32.i32(float 0.0, i32 127) |
| store volatile float %max.exp, ptr addrspace(1) undef |
| |
| %max.exp.plus1 = call float @llvm.ldexp.f32.i32(float 0.0, i32 128) |
| store volatile float %max.exp.plus1, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_f32_undef_strictfp(float %x, i32 %y) #0 { |
| ; CHECK-LABEL: @ldexp_f32_undef_strictfp( |
| ; CHECK-NEXT: [[UNDEF_EXP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X:%.*]], i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[UNDEF_EXP]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float [[X]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float poison, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float poison, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float undef, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %undef.exp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %undef.exp, ptr addrspace(1) undef |
| %poison.exp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 poison, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %poison.exp, ptr addrspace(1) undef |
| %undef.val = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %undef.val, ptr addrspace(1) undef |
| %poison.val = call float @llvm.experimental.constrained.ldexp.f32.i32(float poison, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %poison.val, ptr addrspace(1) undef |
| %poison.undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float poison, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %poison.undef, ptr addrspace(1) undef |
| %undef.poison = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 poison, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %undef.poison, ptr addrspace(1) undef |
| ret void |
| } |
| |
| ; Should be able to ignore strictfp in this case |
| define void @ldexp_f32_0_strictfp(float %x) #0 { |
| ; CHECK-LABEL: @ldexp_f32_0_strictfp( |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[UNKNOWN_ZERO:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X:%.*]], i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[UNKNOWN_ZERO]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[UNKNOWN_UNDEF:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X]], i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[UNKNOWN_UNDEF]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[DENORMAL_0:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[DENORMAL_0]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[DENORMAL_1:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[DENORMAL_1]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0.0, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %zero, ptr addrspace(1) undef |
| |
| %neg.zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float -0.0, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %neg.zero, ptr addrspace(1) undef |
| |
| %one = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0.0, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %one, ptr addrspace(1) undef |
| |
| %unknown.zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %unknown.zero, ptr addrspace(1) undef |
| |
| %unknown.undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %unknown.undef, ptr addrspace(1) undef |
| |
| %denormal.0 = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %denormal.0, ptr addrspace(1) undef |
| |
| %denormal.1 = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0 |
| store volatile float %denormal.1, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_f32() { |
| ; CHECK-LABEL: @ldexp_f32( |
| ; CHECK-NEXT: store volatile float 2.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 4.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 8.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 5.000000e-01, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x3810000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x3800000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x47E0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -2.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -4.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -8.000000e+00, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float -5.000000e-01, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xB810000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xB800000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xC7E0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x44D5000000000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %one.one = call float @llvm.ldexp.f32.i32(float 1.0, i32 1) |
| store volatile float %one.one, ptr addrspace(1) undef |
| |
| %one.two = call float @llvm.ldexp.f32.i32(float 1.0, i32 2) |
| store volatile float %one.two, ptr addrspace(1) undef |
| |
| %one.three = call float @llvm.ldexp.f32.i32(float 1.0, i32 3) |
| store volatile float %one.three, ptr addrspace(1) undef |
| |
| %one.negone = call float @llvm.ldexp.f32.i32(float 1.0, i32 -1) |
| store volatile float %one.negone, ptr addrspace(1) undef |
| |
| %one.min.exp = call float @llvm.ldexp.f32.i32(float 1.0, i32 -126) |
| store volatile float %one.min.exp, ptr addrspace(1) undef |
| |
| %one.min.exp.sub1 = call float @llvm.ldexp.f32.i32(float 1.0, i32 -127) |
| store volatile float %one.min.exp.sub1, ptr addrspace(1) undef |
| |
| %one.max.exp = call float @llvm.ldexp.f32.i32(float 1.0, i32 127) |
| store volatile float %one.max.exp, ptr addrspace(1) undef |
| |
| %one.max.exp.plus1 = call float @llvm.ldexp.f32.i32(float 1.0, i32 128) |
| store volatile float %one.max.exp.plus1, ptr addrspace(1) undef |
| |
| %neg.one.one = call float @llvm.ldexp.f32.i32(float -1.0, i32 1) |
| store volatile float %neg.one.one, ptr addrspace(1) undef |
| |
| %neg.one.two = call float @llvm.ldexp.f32.i32(float -1.0, i32 2) |
| store volatile float %neg.one.two, ptr addrspace(1) undef |
| |
| %neg.one.three = call float @llvm.ldexp.f32.i32(float -1.0, i32 3) |
| store volatile float %neg.one.three, ptr addrspace(1) undef |
| |
| %neg.one.negone = call float @llvm.ldexp.f32.i32(float -1.0, i32 -1) |
| store volatile float %neg.one.negone, ptr addrspace(1) undef |
| |
| %neg.one.min.exp = call float @llvm.ldexp.f32.i32(float -1.0, i32 -126) |
| store volatile float %neg.one.min.exp, ptr addrspace(1) undef |
| |
| %neg.one.min.exp.sub1 = call float @llvm.ldexp.f32.i32(float -1.0, i32 -127) |
| store volatile float %neg.one.min.exp.sub1, ptr addrspace(1) undef |
| |
| %neg.one.max.exp = call float @llvm.ldexp.f32.i32(float -1.0, i32 127) |
| store volatile float %neg.one.max.exp, ptr addrspace(1) undef |
| |
| %neg.one.max.exp.plus1 = call float @llvm.ldexp.f32.i32(float -1.0, i32 128) |
| store volatile float %neg.one.max.exp.plus1, ptr addrspace(1) undef |
| |
| %fortytwo.seven = call float @llvm.ldexp.f32.i32(float 42.0, i32 73) |
| store volatile float %fortytwo.seven, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| ; Technically we should probably flush these depending on the expected |
| ; denormal mode of the function, but no other IR constant folding |
| ; considers this. |
| define void @ldexp_f32_denormal() { |
| ; CHECK-LABEL: @ldexp_f32_denormal( |
| ; CHECK-NEXT: store volatile float 0x380FFFFFC0000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: store volatile float 0x381FFFFFC0000000, ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %denormal.0 = call float @llvm.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0) |
| store volatile float %denormal.0, ptr addrspace(1) undef |
| |
| %denormal.1 = call float @llvm.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1) |
| store volatile float %denormal.1, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_f64() { |
| ; CHECK-LABEL: @ldexp_f64( |
| ; CHECK-NEXT: store volatile double 2.000000e+00, ptr addrspace(1) undef, align 8 |
| ; CHECK-NEXT: store volatile double 4.000000e+00, ptr addrspace(1) undef, align 8 |
| ; CHECK-NEXT: store volatile double 0x44D5000000000000, ptr addrspace(1) undef, align 8 |
| ; CHECK-NEXT: ret void |
| ; |
| %one.one = call double @llvm.ldexp.f64.i32(double 1.0, i32 1) |
| store volatile double %one.one, ptr addrspace(1) undef |
| |
| %one.two = call double @llvm.ldexp.f64.i32(double 1.0, i32 2) |
| store volatile double %one.two, ptr addrspace(1) undef |
| |
| %fortytwo.seven = call double @llvm.ldexp.f64.i32(double 42.0, i32 73) |
| store volatile double %fortytwo.seven, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_f16() { |
| ; CHECK-LABEL: @ldexp_f16( |
| ; CHECK-NEXT: store volatile half 0xH4000, ptr addrspace(1) undef, align 2 |
| ; CHECK-NEXT: store volatile half 0xH4400, ptr addrspace(1) undef, align 2 |
| ; CHECK-NEXT: store volatile half 0xH7C00, ptr addrspace(1) undef, align 2 |
| ; CHECK-NEXT: ret void |
| ; |
| %one.one = call half @llvm.ldexp.f16.i32(half 1.0, i32 1) |
| store volatile half %one.one, ptr addrspace(1) undef |
| |
| %one.two = call half @llvm.ldexp.f16.i32(half 1.0, i32 2) |
| store volatile half %one.two, ptr addrspace(1) undef |
| |
| %fortytwo.seven = call half @llvm.ldexp.f16.i32(half 42.0, i32 73) |
| store volatile half %fortytwo.seven, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @ldexp_ppcf128() { |
| ; CHECK-LABEL: @ldexp_ppcf128( |
| ; CHECK-NEXT: store volatile ppc_fp128 0xMFFF00000000000000000000000000000, ptr addrspace(1) undef, align 16 |
| ; CHECK-NEXT: store volatile ppc_fp128 0xMFFFC0000000000000000000000000000, ptr addrspace(1) undef, align 16 |
| ; CHECK-NEXT: store volatile ppc_fp128 0xM3FD00000000000000000000000000000, ptr addrspace(1) undef, align 16 |
| ; CHECK-NEXT: store volatile ppc_fp128 0xM41700000000000000000000000000000, ptr addrspace(1) undef, align 16 |
| ; CHECK-NEXT: store volatile ppc_fp128 0xMC0700000000000000000000000000000, ptr addrspace(1) undef, align 16 |
| ; CHECK-NEXT: ret void |
| ; |
| %neginf = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMFFF00000000000000000000000000000, i32 0) |
| store volatile ppc_fp128 %neginf, ptr addrspace(1) undef |
| |
| %snan = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMFFFC0000000000000000000000000000, i32 0) |
| store volatile ppc_fp128 %snan, ptr addrspace(1) undef |
| |
| %one.neg2 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000, i32 -2) |
| store volatile ppc_fp128 %one.neg2, ptr addrspace(1) undef |
| |
| %one.24 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000, i32 24) |
| store volatile ppc_fp128 %one.24, ptr addrspace(1) undef |
| |
| %negone.8 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMBFF00000000000000000000000000000, i32 8) |
| store volatile ppc_fp128 %negone.8, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| define void @constant_fold_ldexp_f32_val_strictfp(i32 %y) #0 { |
| ; CHECK-LABEL: @constant_fold_ldexp_f32_val_strictfp( |
| ; CHECK-NEXT: [[SNAN_MAY_TRAP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[SNAN_MAY_TRAP]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[SNAN_MAY_NOT_TRAP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[SNAN_MAY_NOT_TRAP]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[UNKNOWN_ROUNDING:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[UNKNOWN_ROUNDING]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[NORMAL:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[NORMAL]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: [[NORMAL_DOWN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]] |
| ; CHECK-NEXT: store volatile float [[NORMAL_DOWN]], ptr addrspace(1) undef, align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %snan.may.trap = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0 |
| store volatile float %snan.may.trap, ptr addrspace(1) undef |
| |
| %snan.may.not.trap = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0 |
| store volatile float %snan.may.not.trap, ptr addrspace(1) undef |
| |
| %unknown.rounding = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 |
| store volatile float %unknown.rounding, ptr addrspace(1) undef |
| |
| %normal = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0 |
| store volatile float %normal, ptr addrspace(1) undef |
| |
| %normal.down = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.downward", metadata !"fpexcept.ignore") #0 |
| store volatile float %normal.down, ptr addrspace(1) undef |
| |
| ret void |
| } |
| |
| declare half @llvm.ldexp.f16.i32(half, i32) #1 |
| declare float @llvm.ldexp.f32.i32(float, i32) #1 |
| declare double @llvm.ldexp.f64.i32(double, i32) #1 |
| declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #1 |
| declare float @llvm.experimental.constrained.ldexp.f32.i32(float, i32, metadata, metadata) #1 |
| declare ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128, i32) #1 |
| |
| attributes #0 = { strictfp } |
| attributes #1 = { nounwind readnone speculatable } |