| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -S -passes=instcombine < %s | FileCheck %s |
| |
| define i32 @frexp_f32_clamp_min(float %x) { |
| ; CHECK-LABEL: define i32 @frexp_f32_clamp_min( |
| ; CHECK-SAME: float [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: ret i32 [[EXP]] |
| ; |
| %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x) |
| %exp = extractvalue { float, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smax.i32(i32 %exp, i32 -148) |
| ret i32 %clamp |
| } |
| |
| define i16 @frexp_f32_clamp_min_i16(float %x) { |
| ; CHECK-LABEL: define i16 @frexp_f32_clamp_min_i16( |
| ; CHECK-SAME: float [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i16 } @llvm.frexp.f32.i16(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i16 } [[FREXP]], 1 |
| ; CHECK-NEXT: ret i16 [[EXP]] |
| ; |
| %frexp = call { float, i16 } @llvm.frexp.f32.i16(float %x) |
| %exp = extractvalue { float, i16 } %frexp, 1 |
| %clamp = call i16 @llvm.smax.i16(i16 %exp, i16 -148) |
| ret i16 %clamp |
| } |
| |
| define i32 @frexp_f32_clamp_min_off_by_one(float %x) { |
| ; CHECK-LABEL: define i32 @frexp_f32_clamp_min_off_by_one( |
| ; CHECK-SAME: float [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: [[CLAMP:%.*]] = call i32 @llvm.smax.i32(i32 [[EXP]], i32 -147) |
| ; CHECK-NEXT: ret i32 [[CLAMP]] |
| ; |
| %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x) |
| %exp = extractvalue { float, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smax.i32(i32 %exp, i32 -147) |
| ret i32 %clamp |
| } |
| |
| define i32 @frexp_f32_clamp_max(float %x) { |
| ; CHECK-LABEL: define i32 @frexp_f32_clamp_max( |
| ; CHECK-SAME: float [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: ret i32 [[EXP]] |
| ; |
| %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x) |
| %exp = extractvalue { float, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smin.i32(i32 %exp, i32 128) |
| ret i32 %clamp |
| } |
| |
| define i32 @frexp_f32_clamp_max_off_by_one(float %x) { |
| ; CHECK-LABEL: define i32 @frexp_f32_clamp_max_off_by_one( |
| ; CHECK-SAME: float [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: [[CLAMP:%.*]] = call i32 @llvm.smin.i32(i32 [[EXP]], i32 127) |
| ; CHECK-NEXT: ret i32 [[CLAMP]] |
| ; |
| %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x) |
| %exp = extractvalue { float, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smin.i32(i32 %exp, i32 127) |
| ret i32 %clamp |
| } |
| |
| define i32 @frexp_f32_clamp_min_no_denormal(float nofpclass(sub) %x) { |
| ; CHECK-LABEL: define i32 @frexp_f32_clamp_min_no_denormal( |
| ; CHECK-SAME: float nofpclass(sub) [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: ret i32 [[EXP]] |
| ; |
| %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x) |
| %exp = extractvalue { float, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smax.i32(i32 %exp, i32 -125) |
| ret i32 %clamp |
| } |
| |
| define i32 @frexp_f32_clamp_min_no_denormal_off_by_one(float nofpclass(sub) %x) { |
| ; CHECK-LABEL: define i32 @frexp_f32_clamp_min_no_denormal_off_by_one( |
| ; CHECK-SAME: float nofpclass(sub) [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { float, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: [[CLAMP:%.*]] = call i32 @llvm.smax.i32(i32 [[EXP]], i32 -124) |
| ; CHECK-NEXT: ret i32 [[CLAMP]] |
| ; |
| %frexp = call { float, i32 } @llvm.frexp.f32.i32(float %x) |
| %exp = extractvalue { float, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smax.i32(i32 %exp, i32 -124) |
| ret i32 %clamp |
| } |
| |
| define <2 x i32> @frexp_v2f32_clamp_min(<2 x float> %x) { |
| ; CHECK-LABEL: define <2 x i32> @frexp_v2f32_clamp_min( |
| ; CHECK-SAME: <2 x float> [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { <2 x float>, <2 x i32> } [[FREXP]], 1 |
| ; CHECK-NEXT: ret <2 x i32> [[EXP]] |
| ; |
| %frexp = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %x) |
| %exp = extractvalue { <2 x float>, <2 x i32> } %frexp, 1 |
| %clamp = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %exp, <2 x i32> splat (i32 -148)) |
| ret <2 x i32> %clamp |
| } |
| |
| |
| define i32 @frexp_f64_clamp_min(double %x) { |
| ; CHECK-LABEL: define i32 @frexp_f64_clamp_min( |
| ; CHECK-SAME: double [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { double, i32 } @llvm.frexp.f64.i32(double [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { double, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: ret i32 [[EXP]] |
| ; |
| %frexp = call { double, i32 } @llvm.frexp.f32.i32(double %x) |
| %exp = extractvalue { double, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smax.i32(i32 %exp, i32 -1073) |
| ret i32 %clamp |
| } |
| |
| define i32 @frexp_f64_clamp_max(double %x) { |
| ; CHECK-LABEL: define i32 @frexp_f64_clamp_max( |
| ; CHECK-SAME: double [[X:%.*]]) { |
| ; CHECK-NEXT: [[FREXP:%.*]] = call { double, i32 } @llvm.frexp.f64.i32(double [[X]]) |
| ; CHECK-NEXT: [[EXP:%.*]] = extractvalue { double, i32 } [[FREXP]], 1 |
| ; CHECK-NEXT: ret i32 [[EXP]] |
| ; |
| %frexp = call { double, i32 } @llvm.frexp.f32.i32(double %x) |
| %exp = extractvalue { double, i32 } %frexp, 1 |
| %clamp = call i32 @llvm.smin.i32(i32 %exp, i32 1024) |
| ret i32 %clamp |
| } |