| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=instsimplify -S < %s | FileCheck %s |
| |
| declare float @llvm.fabs.f32(float) |
| declare float @llvm.pow.f32(float, float) |
| declare <2 x float> @llvm.fabs.v2f32(<2 x float>) |
| declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) |
| |
| define i1 @pow_fabs_olt_zero(float %base, float %exp) { |
| ; CHECK-LABEL: define i1 @pow_fabs_olt_zero( |
| ; CHECK-SAME: float [[BASE:%.*]], float [[EXP:%.*]]) { |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %abs = call float @llvm.fabs.f32(float %base) |
| %pow = call float @llvm.pow.f32(float %abs, float %exp) |
| %cmp = fcmp olt float %pow, 0.0 |
| ret i1 %cmp |
| } |
| |
| define float @fabs_pow_nonneg_base(float nofpclass(nan) %base, float nofpclass(nan) %exp) { |
| ; CHECK-LABEL: define float @fabs_pow_nonneg_base( |
| ; CHECK-SAME: float nofpclass(nan) [[BASE:%.*]], float nofpclass(nan) [[EXP:%.*]]) { |
| ; CHECK-NEXT: [[ABS_BASE:%.*]] = call float @llvm.fabs.f32(float [[BASE]]) |
| ; CHECK-NEXT: [[POW:%.*]] = call float @llvm.pow.f32(float [[ABS_BASE]], float [[EXP]]) |
| ; CHECK-NEXT: ret float [[POW]] |
| ; |
| %abs.base = call float @llvm.fabs.f32(float %base) |
| %pow = call float @llvm.pow.f32(float %abs.base, float %exp) |
| %abs.pow = call float @llvm.fabs.f32(float %pow) |
| ret float %abs.pow |
| } |
| |
| define i1 @pow_nonnormal_exponent_olt_zero(float %base, float nofpclass(norm) %exp) { |
| ; CHECK-LABEL: define i1 @pow_nonnormal_exponent_olt_zero( |
| ; CHECK-SAME: float [[BASE:%.*]], float nofpclass(norm) [[EXP:%.*]]) { |
| ; CHECK-NEXT: [[POW:%.*]] = call float @llvm.pow.f32(float [[BASE]], float [[EXP]]) |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[POW]], 0.000000e+00 |
| ; CHECK-NEXT: ret i1 [[CMP]] |
| ; |
| %pow = call float @llvm.pow.f32(float %base, float %exp) |
| %cmp = fcmp olt float %pow, 0.0 |
| ret i1 %cmp |
| } |
| |
| define i1 @isnan_pow_nonneg_or_negzero_base(float nofpclass(nan ninf nsub nnorm) %base, float nofpclass(nan) %exp) { |
| ; CHECK-LABEL: define i1 @isnan_pow_nonneg_or_negzero_base( |
| ; CHECK-SAME: float nofpclass(nan ninf nsub nnorm) [[BASE:%.*]], float nofpclass(nan) [[EXP:%.*]]) { |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %pow = call float @llvm.pow.f32(float %base, float %exp) |
| %isnan = fcmp uno float %pow, %pow |
| ret i1 %isnan |
| } |
| |
| ; qNaN may be produced when a negative base is raised to a non-integer exponent. |
| define i1 @isnan_pow_negative_base(float nofpclass(nan inf zero psub pnorm) %base, float nofpclass(nan) %exp) { |
| ; CHECK-LABEL: define i1 @isnan_pow_negative_base( |
| ; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[BASE:%.*]], float nofpclass(nan) [[EXP:%.*]]) { |
| ; CHECK-NEXT: [[POW:%.*]] = call float @llvm.pow.f32(float [[BASE]], float [[EXP]]) |
| ; CHECK-NEXT: [[ISNAN:%.*]] = fcmp uno float [[POW]], [[POW]] |
| ; CHECK-NEXT: ret i1 [[ISNAN]] |
| ; |
| %pow = call float @llvm.pow.f32(float %base, float %exp) |
| %isnan = fcmp uno float %pow, %pow |
| ret i1 %isnan |
| } |
| |
| ; A negative result is produced when a negative base is raised to an odd integer |
| ; exponent. |
| define float @fabs_pow_negative_base_normal_exponent(float nofpclass(nan inf zero psub pnorm) %base, float nofpclass(nan inf zero sub) %exp) { |
| ; CHECK-LABEL: define float @fabs_pow_negative_base_normal_exponent( |
| ; CHECK-SAME: float nofpclass(nan inf zero psub pnorm) [[BASE:%.*]], float nofpclass(nan inf zero sub) [[EXP:%.*]]) { |
| ; CHECK-NEXT: [[POW:%.*]] = call float @llvm.pow.f32(float [[BASE]], float [[EXP]]) |
| ; CHECK-NEXT: [[ABS_POW:%.*]] = call float @llvm.fabs.f32(float [[POW]]) |
| ; CHECK-NEXT: ret float [[ABS_POW]] |
| ; |
| %pow = call float @llvm.pow.f32(float %base, float %exp) |
| %abs.pow = call float @llvm.fabs.f32(float %pow) |
| ret float %abs.pow |
| } |
| |
| define <2 x i1> @pow_fabs_olt_zero_v2f32(<2 x float> %base, <2 x float> %exp) { |
| ; CHECK-LABEL: define <2 x i1> @pow_fabs_olt_zero_v2f32( |
| ; CHECK-SAME: <2 x float> [[BASE:%.*]], <2 x float> [[EXP:%.*]]) { |
| ; CHECK-NEXT: ret <2 x i1> zeroinitializer |
| ; |
| %abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %base) |
| %pow = call <2 x float> @llvm.pow.v2f32(<2 x float> %abs, <2 x float> %exp) |
| %cmp = fcmp olt <2 x float> %pow, zeroinitializer |
| ret <2 x i1> %cmp |
| } |
| |
| define <2 x i1> @isnan_pow_nonneg_or_negzero_base_v2f32(<2 x float> nofpclass(nan ninf nsub nnorm) %base, <2 x float> nofpclass(nan) %exp) { |
| ; CHECK-LABEL: define <2 x i1> @isnan_pow_nonneg_or_negzero_base_v2f32( |
| ; CHECK-SAME: <2 x float> nofpclass(nan ninf nsub nnorm) [[BASE:%.*]], <2 x float> nofpclass(nan) [[EXP:%.*]]) { |
| ; CHECK-NEXT: ret <2 x i1> zeroinitializer |
| ; |
| %pow = call <2 x float> @llvm.pow.v2f32(<2 x float> %base, <2 x float> %exp) |
| %isnan = fcmp uno <2 x float> %pow, %pow |
| ret <2 x i1> %isnan |
| } |