ValueTracking: x - floor(x) cannot introduce overflow (#189003)
This returns a value with an absolute value less than 1 so it should be possible to propagate no-infs.
This commit is contained in:
parent
0abef30c80
commit
2ec19b86b5
@ -4973,9 +4973,17 @@ static constexpr KnownFPClass::MinMaxKind getMinMaxKind(Intrinsic::ID IID) {
|
||||
}
|
||||
|
||||
/// \return true if this is a floating point value that is known to have a
|
||||
/// magnitude smaller than 1. i.e., fabs(X) <= 1.0
|
||||
static bool isAbsoluteValueLessEqualOne(const Value *V) {
|
||||
// TODO: Handle frexp and x - floor(x)?
|
||||
/// magnitude smaller than 1. i.e., fabs(X) <= 1.0 or is nan.
|
||||
static bool isAbsoluteValueULEOne(const Value *V) {
|
||||
// TODO: Handle frexp
|
||||
// TODO: Other rounding intrinsics?
|
||||
|
||||
// fabs(x - floor(x)) <= 1
|
||||
const Value *SubFloorX;
|
||||
if (match(V, m_FSub(m_Value(SubFloorX),
|
||||
m_Intrinsic<Intrinsic::floor>(m_Deferred(SubFloorX)))))
|
||||
return true;
|
||||
|
||||
return match(V, m_Intrinsic<Intrinsic::amdgcn_trig_preop>(m_Value())) ||
|
||||
match(V, m_Intrinsic<Intrinsic::amdgcn_fract>(m_Value()));
|
||||
}
|
||||
@ -5645,9 +5653,9 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
|
||||
|
||||
/// Propgate no-infs if the other source is known smaller than one, such
|
||||
/// that this cannot introduce overflow.
|
||||
if (KnownLHS.isKnownNever(fcInf) && isAbsoluteValueLessEqualOne(RHS))
|
||||
if (KnownLHS.isKnownNever(fcInf) && isAbsoluteValueULEOne(RHS))
|
||||
Known.knownNot(fcInf);
|
||||
else if (KnownRHS.isKnownNever(fcInf) && isAbsoluteValueLessEqualOne(LHS))
|
||||
else if (KnownRHS.isKnownNever(fcInf) && isAbsoluteValueULEOne(LHS))
|
||||
Known.knownNot(fcInf);
|
||||
|
||||
break;
|
||||
|
||||
@ -910,3 +910,45 @@ define float @ret_fmul__not_inf__neg1.5(float nofpclass(inf) %x) {
|
||||
%mul = fmul float %x, -1.5
|
||||
ret float %mul
|
||||
}
|
||||
|
||||
define float @ret_fmul__not_inf__fsub_floor_pat(float nofpclass(inf) %x, float %y) {
|
||||
; CHECK-LABEL: define nofpclass(inf) float @ret_fmul__not_inf__fsub_floor_pat(
|
||||
; CHECK-SAME: float nofpclass(inf) [[X:%.*]], float [[Y:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: [[FLOOR_Y:%.*]] = call float @llvm.floor.f32(float [[Y]]) #[[ATTR2]]
|
||||
; CHECK-NEXT: [[Y_SUB_FLOOR_Y:%.*]] = fsub float [[Y]], [[FLOOR_Y]]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[Y_SUB_FLOOR_Y]]
|
||||
; CHECK-NEXT: ret float [[MUL]]
|
||||
;
|
||||
%floor.y = call float @llvm.floor.f32(float %y)
|
||||
%y.sub.floor.y = fsub float %y, %floor.y
|
||||
%mul = fmul float %x, %y.sub.floor.y
|
||||
ret float %mul
|
||||
}
|
||||
|
||||
define float @ret_fmul__not_inf__fsub_floor_pat_commute(float nofpclass(inf) %x, float %y) {
|
||||
; CHECK-LABEL: define nofpclass(inf) float @ret_fmul__not_inf__fsub_floor_pat_commute(
|
||||
; CHECK-SAME: float nofpclass(inf) [[X:%.*]], float [[Y:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: [[FLOOR_Y:%.*]] = call float @llvm.floor.f32(float [[Y]]) #[[ATTR2]]
|
||||
; CHECK-NEXT: [[Y_SUB_FLOOR_Y:%.*]] = fsub float [[Y]], [[FLOOR_Y]]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[Y_SUB_FLOOR_Y]], [[X]]
|
||||
; CHECK-NEXT: ret float [[MUL]]
|
||||
;
|
||||
%floor.y = call float @llvm.floor.f32(float %y)
|
||||
%y.sub.floor.y = fsub float %y, %floor.y
|
||||
%mul = fmul float %y.sub.floor.y, %x
|
||||
ret float %mul
|
||||
}
|
||||
|
||||
define float @ret_fmul__not_inf__fsub_floor_pat_wrong_floor_val(float nofpclass(inf) %x, float %y, float %z) {
|
||||
; CHECK-LABEL: define float @ret_fmul__not_inf__fsub_floor_pat_wrong_floor_val(
|
||||
; CHECK-SAME: float nofpclass(inf) [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: [[FLOOR_Y:%.*]] = call float @llvm.floor.f32(float [[Z]]) #[[ATTR2]]
|
||||
; CHECK-NEXT: [[Y_SUB_FLOOR_Y:%.*]] = fsub float [[Y]], [[FLOOR_Y]]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[X]], [[Y_SUB_FLOOR_Y]]
|
||||
; CHECK-NEXT: ret float [[MUL]]
|
||||
;
|
||||
%floor.y = call float @llvm.floor.f32(float %z)
|
||||
%y.sub.floor.y = fsub float %y, %floor.y
|
||||
%mul = fmul float %x, %y.sub.floor.y
|
||||
ret float %mul
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user