Skip to content

Commit 2c6cad1

Browse files
committed
[IR] Handle fabs LHS in fcmpImpliesClass
1 parent 7ac29cb commit 2c6cad1

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

llvm/include/llvm/IR/GenericFloatingPointPredicateUtils.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,26 +151,40 @@ template <typename ContextT> class GenericFloatingPointPredicateUtils {
151151
case FCmpInst::FCMP_UNO:
152152
return exactClass(Src, fcNan);
153153
case FCmpInst::FCMP_OGT: // x > 0
154+
if (IsFabs)
155+
return exactClass(Src, fcSubnormal | fcNormal | fcInf);
154156
return exactClass(Src, fcPosSubnormal | fcPosNormal | fcPosInf);
155157
case FCmpInst::FCMP_UGT: // isnan(x) || x > 0
158+
if (IsFabs)
159+
return exactClass(Src, fcSubnormal | fcNormal | fcInf | fcNan);
156160
return exactClass(Src, fcPosSubnormal | fcPosNormal | fcPosInf | fcNan);
157161
case FCmpInst::FCMP_OGE: // x >= 0
162+
if (IsFabs)
163+
return exactClass(Src, ~fcNan);
158164
return exactClass(Src, fcPositive | fcNegZero);
159165
case FCmpInst::FCMP_UGE: // isnan(x) || x >= 0
166+
if (IsFabs)
167+
return exactClass(Src, fcAllFlags);
160168
return exactClass(Src, fcPositive | fcNegZero | fcNan);
161169
case FCmpInst::FCMP_OLT: // x < 0
170+
if (IsFabs)
171+
return exactClass(Src, fcNone);
162172
return exactClass(Src, fcNegSubnormal | fcNegNormal | fcNegInf);
163173
case FCmpInst::FCMP_ULT: // isnan(x) || x < 0
174+
if (IsFabs)
175+
return exactClass(Src, fcNan);
164176
return exactClass(Src, fcNegSubnormal | fcNegNormal | fcNegInf | fcNan);
165177
case FCmpInst::FCMP_OLE: // x <= 0
178+
if (IsFabs)
179+
return exactClass(Src, fcZero);
166180
return exactClass(Src, fcNegative | fcPosZero);
167181
case FCmpInst::FCMP_ULE: // isnan(x) || x <= 0
182+
if (IsFabs)
183+
return exactClass(Src, fcZero | fcNan);
168184
return exactClass(Src, fcNegative | fcPosZero | fcNan);
169185
default:
170186
llvm_unreachable("all compare types are handled");
171187
}
172-
173-
return {Invalid, fcAllFlags, fcAllFlags};
174188
}
175189

176190
const bool IsDenormalRHS = (OrigClass & fcSubnormal) == OrigClass;

llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,8 @@ define half @fabs_select_fabs(half noundef %x) {
12621262
; CHECK-NEXT: [[ABS1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
12631263
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt half [[ABS1]], 0xH0000
12641264
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], half [[X]], half 0xH0000
1265-
; CHECK-NEXT: ret half [[SEL]]
1265+
; CHECK-NEXT: [[ABS2:%.*]] = call half @llvm.fabs.f16(half [[SEL]])
1266+
; CHECK-NEXT: ret half [[ABS2]]
12661267
;
12671268
entry:
12681269
%abs1 = call half @llvm.fabs.f16(half %x)

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/Analysis/ValueTracking.h"
10+
#include "llvm/ADT/FloatingPointMode.h"
1011
#include "llvm/Analysis/AssumptionCache.h"
1112
#include "llvm/Analysis/FloatingPointPredicateUtils.h"
1213
#include "llvm/AsmParser/Parser.h"
@@ -2208,6 +2209,41 @@ TEST_F(ComputeKnownFPClassTest, Constants) {
22082209
}
22092210
}
22102211

2212+
TEST_F(ComputeKnownFPClassTest, fcmpImpliesClass_fabs_zero) {
2213+
parseAssembly("define float @test(float %x) {\n"
2214+
" %A = call float @llvm.fabs.f32(float %x)\n"
2215+
" ret float %A\n"
2216+
"}\n");
2217+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OEQ, *F, A, fcZero)),
2218+
fcZero);
2219+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UEQ, *F, A, fcZero)),
2220+
fcZero | fcNan);
2221+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UNE, *F, A, fcZero)),
2222+
~fcZero);
2223+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ONE, *F, A, fcZero)),
2224+
~fcNan & ~fcZero);
2225+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ORD, *F, A, fcZero)),
2226+
~fcNan);
2227+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UNO, *F, A, fcZero)),
2228+
fcNan);
2229+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OGT, *F, A, fcZero)),
2230+
fcSubnormal | fcNormal | fcInf);
2231+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UGT, *F, A, fcZero)),
2232+
fcSubnormal | fcNormal | fcInf | fcNan);
2233+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OGE, *F, A, fcZero)),
2234+
~fcNan);
2235+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_UGE, *F, A, fcZero)),
2236+
fcAllFlags);
2237+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OLT, *F, A, fcZero)),
2238+
fcNone);
2239+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ULT, *F, A, fcZero)),
2240+
fcNan);
2241+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_OLE, *F, A, fcZero)),
2242+
fcZero);
2243+
EXPECT_EQ(std::get<1>(fcmpImpliesClass(FCmpInst::FCMP_ULE, *F, A, fcZero)),
2244+
fcZero | fcNan);
2245+
}
2246+
22112247
TEST_F(ValueTrackingTest, isNonZeroRecurrence) {
22122248
parseAssembly(R"(
22132249
define i1 @test(i8 %n, i8 %r) {

0 commit comments

Comments
 (0)