Skip to content

Commit e710a5a

Browse files
authored
[InstCombine] Fold fneg/fabs patterns with ppc_f128 (#130557)
This patch is needed by #130496.
1 parent ffd5b14 commit e710a5a

File tree

7 files changed

+39
-12
lines changed

7 files changed

+39
-12
lines changed

llvm/include/llvm/ADT/APFloat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ struct APFloatBase {
354354
static bool semanticsHasInf(const fltSemantics &);
355355
static bool semanticsHasNaN(const fltSemantics &);
356356
static bool isIEEELikeFP(const fltSemantics &);
357+
static bool hasSignBitInMSB(const fltSemantics &);
357358

358359
// Returns true if any number described by \p Src can be precisely represented
359360
// by a normal (not subnormal) value in \p Dst.

llvm/lib/Support/APFloat.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ struct fltSemantics {
125125

126126
/* Whether this semantics can represent signed values */
127127
bool hasSignedRepr = true;
128+
129+
/* Whether the sign bit of this semantics is the most significant bit */
130+
bool hasSignBitInMSB = true;
128131
};
129132

130133
static constexpr fltSemantics semIEEEhalf = {15, -14, 11, 16};
@@ -144,9 +147,15 @@ static constexpr fltSemantics semFloat8E4M3B11FNUZ = {
144147
4, -10, 4, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
145148
static constexpr fltSemantics semFloat8E3M4 = {3, -2, 5, 8};
146149
static constexpr fltSemantics semFloatTF32 = {127, -126, 11, 19};
147-
static constexpr fltSemantics semFloat8E8M0FNU = {
148-
127, -127, 1, 8, fltNonfiniteBehavior::NanOnly, fltNanEncoding::AllOnes,
149-
false, false};
150+
static constexpr fltSemantics semFloat8E8M0FNU = {127,
151+
-127,
152+
1,
153+
8,
154+
fltNonfiniteBehavior::NanOnly,
155+
fltNanEncoding::AllOnes,
156+
false,
157+
false,
158+
false};
150159

151160
static constexpr fltSemantics semFloat6E3M2FN = {
152161
4, -2, 3, 6, fltNonfiniteBehavior::FiniteOnly};
@@ -358,6 +367,10 @@ bool APFloatBase::isIEEELikeFP(const fltSemantics &semantics) {
358367
return SemanticsToEnum(semantics) <= S_IEEEquad;
359368
}
360369

370+
bool APFloatBase::hasSignBitInMSB(const fltSemantics &semantics) {
371+
return semantics.hasSignBitInMSB;
372+
}
373+
361374
bool APFloatBase::isRepresentableAsNormalIn(const fltSemantics &Src,
362375
const fltSemantics &Dst) {
363376
// Exponent range must be larger.

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,7 +2645,8 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
26452645
!Builder.GetInsertBlock()->getParent()->hasFnAttribute(
26462646
Attribute::NoImplicitFloat)) {
26472647
Type *EltTy = CastOp->getType()->getScalarType();
2648-
if (EltTy->isFloatingPointTy() && EltTy->isIEEE()) {
2648+
if (EltTy->isFloatingPointTy() &&
2649+
APFloat::hasSignBitInMSB(EltTy->getFltSemantics())) {
26492650
Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
26502651
return new BitCastInst(FAbs, I.getType());
26512652
}
@@ -4058,7 +4059,8 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
40584059
!Builder.GetInsertBlock()->getParent()->hasFnAttribute(
40594060
Attribute::NoImplicitFloat)) {
40604061
Type *EltTy = CastOp->getType()->getScalarType();
4061-
if (EltTy->isFloatingPointTy() && EltTy->isIEEE()) {
4062+
if (EltTy->isFloatingPointTy() &&
4063+
APFloat::hasSignBitInMSB(EltTy->getFltSemantics())) {
40624064
Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
40634065
Value *FNegFAbs = Builder.CreateFNeg(FAbs);
40644066
return new BitCastInst(FNegFAbs, I.getType());
@@ -4860,7 +4862,8 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
48604862
!Builder.GetInsertBlock()->getParent()->hasFnAttribute(
48614863
Attribute::NoImplicitFloat)) {
48624864
Type *EltTy = CastOp->getType()->getScalarType();
4863-
if (EltTy->isFloatingPointTy() && EltTy->isIEEE()) {
4865+
if (EltTy->isFloatingPointTy() &&
4866+
APFloat::hasSignBitInMSB(EltTy->getFltSemantics())) {
48644867
Value *FNeg = Builder.CreateFNeg(CastOp);
48654868
return new BitCastInst(FNeg, I.getType());
48664869
}

llvm/test/Transforms/InstCombine/fabs-as-int.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ define i128 @fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
289289
define i128 @fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
290290
; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f128_mask
291291
; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
292-
; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
293-
; CHECK-NEXT: [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727
292+
; CHECK-NEXT: [[TMP1:%.*]] = call ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 [[X]])
293+
; CHECK-NEXT: [[AND:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128
294294
; CHECK-NEXT: ret i128 [[AND]]
295295
;
296296
%bc = bitcast ppc_fp128 %x to i128

llvm/test/Transforms/InstCombine/fneg-as-int.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ define i128 @fneg_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
291291
define i128 @fneg_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
292292
; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f128_mask
293293
; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
294-
; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
295-
; CHECK-NEXT: [[XOR:%.*]] = xor i128 [[BC]], -170141183460469231731687303715884105728
294+
; CHECK-NEXT: [[TMP1:%.*]] = fneg ppc_fp128 [[X]]
295+
; CHECK-NEXT: [[XOR:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128
296296
; CHECK-NEXT: ret i128 [[XOR]]
297297
;
298298
%bc = bitcast ppc_fp128 %x to i128

llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,9 @@ define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
317317
define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
318318
; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask
319319
; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
320-
; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
321-
; CHECK-NEXT: [[OR:%.*]] = or i128 [[BC]], -170141183460469231731687303715884105728
320+
; CHECK-NEXT: [[TMP1:%.*]] = call ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 [[X]])
321+
; CHECK-NEXT: [[TMP2:%.*]] = fneg ppc_fp128 [[TMP1]]
322+
; CHECK-NEXT: [[OR:%.*]] = bitcast ppc_fp128 [[TMP2]] to i128
322323
; CHECK-NEXT: ret i128 [[OR]]
323324
;
324325
%bc = bitcast ppc_fp128 %x to i128

llvm/unittests/ADT/APFloatTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8347,4 +8347,13 @@ TEST(APFloatTest, AddOrSubtractSignificand) {
83478347
Helper::runTest(true, false, 3, 0x10001, false, 7, 0x100, false, 6, 0x1e00,
83488348
lfLessThanHalf);
83498349
}
8350+
8351+
TEST(APFloatTest, hasSignBitInMSB) {
8352+
EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::IEEEsingle()));
8353+
EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::x87DoubleExtended()));
8354+
EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::PPCDoubleDouble()));
8355+
EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::IEEEquad()));
8356+
EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E8M0FNU()));
8357+
}
8358+
83508359
} // namespace

0 commit comments

Comments
 (0)