[llvm] [IR][ADT][InstCombine] Remove `APFloat/Type::isIEEE` (PR #130496)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 9 09:43:32 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
Address comment https://github.com/llvm/llvm-project/pull/130477#issuecomment-2708801892.
Specifically, we allow InstCombine to handle bitwise fabs/fneg operations with ppc_fp128.
---
Full diff: https://github.com/llvm/llvm-project/pull/130496.diff
9 Files Affected:
- (modified) llvm/include/llvm/ADT/APFloat.h (-1)
- (modified) llvm/include/llvm/IR/Type.h (+2-6)
- (modified) llvm/include/llvm/SandboxIR/Type.h (+2-6)
- (modified) llvm/lib/IR/Type.cpp (-4)
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+13-22)
- (modified) llvm/test/Transforms/InstCombine/fabs-as-int.ll (+2-2)
- (modified) llvm/test/Transforms/InstCombine/fneg-as-int.ll (+2-2)
- (modified) llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll (+3-2)
- (modified) llvm/unittests/SandboxIR/TypesTest.cpp (+2-2)
``````````diff
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 00d92740259eb..803fb59723eaf 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1462,7 +1462,6 @@ class APFloat : public APFloatBase {
bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); }
bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); }
bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); }
- bool isIEEE() const { return usesLayout<IEEEFloat>(getSemantics()); }
bool isSmallestNormalized() const {
APFLOAT_DISPATCH_ON_SEMANTICS(isSmallestNormalized());
diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h
index 6dadf158a739f..a4c0648a9197e 100644
--- a/llvm/include/llvm/IR/Type.h
+++ b/llvm/include/llvm/IR/Type.h
@@ -165,8 +165,8 @@ class Type {
bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }
/// Return true if this is a well-behaved IEEE-like type, which has a IEEE
- /// compatible layout as defined by APFloat::isIEEE(), and does not have
- /// non-IEEE values, such as x86_fp80's unnormal values.
+ /// compatible layout, and does not have non-IEEE values, such as x86_fp80's
+ /// unnormal values.
bool isIEEELikeFPTy() const {
switch (getTypeID()) {
case DoubleTyID:
@@ -346,10 +346,6 @@ class Type {
/// ppc long double), this method returns -1.
int getFPMantissaWidth() const;
- /// Return whether the type is IEEE compatible, as defined by the eponymous
- /// method in APFloat.
- bool isIEEE() const;
-
/// If this is a vector type, return the element type, otherwise return
/// 'this'.
inline Type *getScalarType() const {
diff --git a/llvm/include/llvm/SandboxIR/Type.h b/llvm/include/llvm/SandboxIR/Type.h
index ec32284dacd61..b7ca0f9e40af9 100644
--- a/llvm/include/llvm/SandboxIR/Type.h
+++ b/llvm/include/llvm/SandboxIR/Type.h
@@ -116,8 +116,8 @@ class Type {
bool isPPC_FP128Ty() const { return LLVMTy->isPPC_FP128Ty(); }
/// Return true if this is a well-behaved IEEE-like type, which has a IEEE
- /// compatible layout as defined by APFloat::isIEEE(), and does not have
- /// non-IEEE values, such as x86_fp80's unnormal values.
+ /// compatible layout, and does not have non-IEEE values, such as x86_fp80's
+ /// unnormal values.
bool isIEEELikeFPTy() const { return LLVMTy->isIEEELikeFPTy(); }
/// Return true if this is one of the floating-point types
@@ -258,10 +258,6 @@ class Type {
/// ppc long double), this method returns -1.
int getFPMantissaWidth() const { return LLVMTy->getFPMantissaWidth(); }
- /// Return whether the type is IEEE compatible, as defined by the eponymous
- /// method in APFloat.
- bool isIEEE() const { return LLVMTy->isIEEE(); }
-
/// If this is a vector type, return the element type, otherwise return
/// 'this'.
Type *getScalarType() const;
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 277985b6b00a3..4a38505ad3f48 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -117,10 +117,6 @@ const fltSemantics &Type::getFltSemantics() const {
}
}
-bool Type::isIEEE() const {
- return APFloat::getZero(getFltSemantics()).isIEEE();
-}
-
bool Type::isScalableTargetExtTy() const {
if (auto *TT = dyn_cast<TargetExtType>(this))
return isa<ScalableVectorType>(TT->getLayoutType());
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 6cc241781d112..8394cbb5e3183 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2637,18 +2637,15 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
// This is a generous interpretation for noimplicitfloat, this is not a true
// floating-point operation.
//
- // Assumes any IEEE-represented type has the sign bit in the high bit.
+ // Assumes any floating point type has the sign bit in the high bit.
// TODO: Unify with APInt matcher. This version allows undef unlike m_APInt
Value *CastOp;
if (match(Op0, m_ElementWiseBitCast(m_Value(CastOp))) &&
- match(Op1, m_MaxSignedValue()) &&
+ CastOp->getType()->isFPOrFPVectorTy() && match(Op1, m_MaxSignedValue()) &&
!Builder.GetInsertBlock()->getParent()->hasFnAttribute(
Attribute::NoImplicitFloat)) {
- Type *EltTy = CastOp->getType()->getScalarType();
- if (EltTy->isFloatingPointTy() && EltTy->isIEEE()) {
- Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
- return new BitCastInst(FAbs, I.getType());
- }
+ Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
+ return new BitCastInst(FAbs, I.getType());
}
// and(shl(zext(X), Y), SignMask) -> and(sext(X), SignMask)
@@ -4047,21 +4044,18 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
// the number of instructions. This is still probably a better canonical form
// as it enables FP value tracking.
//
- // Assumes any IEEE-represented type has the sign bit in the high bit.
+ // Assumes any floating point type has the sign bit in the high bit.
//
// This is generous interpretation of noimplicitfloat, this is not a true
// floating-point operation.
Value *CastOp;
if (match(Op0, m_ElementWiseBitCast(m_Value(CastOp))) &&
- match(Op1, m_SignMask()) &&
+ CastOp->getType()->isFPOrFPVectorTy() && match(Op1, m_SignMask()) &&
!Builder.GetInsertBlock()->getParent()->hasFnAttribute(
Attribute::NoImplicitFloat)) {
- Type *EltTy = CastOp->getType()->getScalarType();
- if (EltTy->isFloatingPointTy() && EltTy->isIEEE()) {
- Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
- Value *FNegFAbs = Builder.CreateFNeg(FAbs);
- return new BitCastInst(FNegFAbs, I.getType());
- }
+ Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, CastOp);
+ Value *FNegFAbs = Builder.CreateFNeg(FAbs);
+ return new BitCastInst(FNegFAbs, I.getType());
}
// (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C2
@@ -4851,18 +4845,15 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
// This is generous interpretation of noimplicitfloat, this is not a true
// floating-point operation.
//
- // Assumes any IEEE-represented type has the sign bit in the high bit.
+ // Assumes any floating point type has the sign bit in the high bit.
// TODO: Unify with APInt matcher. This version allows undef unlike m_APInt
Value *CastOp;
if (match(Op0, m_ElementWiseBitCast(m_Value(CastOp))) &&
- match(Op1, m_SignMask()) &&
+ CastOp->getType()->isFPOrFPVectorTy() && match(Op1, m_SignMask()) &&
!Builder.GetInsertBlock()->getParent()->hasFnAttribute(
Attribute::NoImplicitFloat)) {
- Type *EltTy = CastOp->getType()->getScalarType();
- if (EltTy->isFloatingPointTy() && EltTy->isIEEE()) {
- Value *FNeg = Builder.CreateFNeg(CastOp);
- return new BitCastInst(FNeg, I.getType());
- }
+ Value *FNeg = Builder.CreateFNeg(CastOp);
+ return new BitCastInst(FNeg, I.getType());
}
}
diff --git a/llvm/test/Transforms/InstCombine/fabs-as-int.ll b/llvm/test/Transforms/InstCombine/fabs-as-int.ll
index 9d28cae8f04d6..f0e83ca6302fe 100644
--- a/llvm/test/Transforms/InstCombine/fabs-as-int.ll
+++ b/llvm/test/Transforms/InstCombine/fabs-as-int.ll
@@ -289,8 +289,8 @@ define i128 @fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
define i128 @fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
; CHECK-LABEL: define i128 @fabs_as_int_ppc_fp128_f128_mask
; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
-; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
-; CHECK-NEXT: [[AND:%.*]] = and i128 [[BC]], 170141183460469231731687303715884105727
+; CHECK-NEXT: [[TMP1:%.*]] = call ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 [[X]])
+; CHECK-NEXT: [[AND:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128
; CHECK-NEXT: ret i128 [[AND]]
;
%bc = bitcast ppc_fp128 %x to i128
diff --git a/llvm/test/Transforms/InstCombine/fneg-as-int.ll b/llvm/test/Transforms/InstCombine/fneg-as-int.ll
index f8d88b4f238f2..590aca687e5b5 100644
--- a/llvm/test/Transforms/InstCombine/fneg-as-int.ll
+++ b/llvm/test/Transforms/InstCombine/fneg-as-int.ll
@@ -291,8 +291,8 @@ define i128 @fneg_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
define i128 @fneg_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
; CHECK-LABEL: define i128 @fneg_as_int_ppc_fp128_f128_mask
; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
-; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
-; CHECK-NEXT: [[XOR:%.*]] = xor i128 [[BC]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[TMP1:%.*]] = fneg ppc_fp128 [[X]]
+; CHECK-NEXT: [[XOR:%.*]] = bitcast ppc_fp128 [[TMP1]] to i128
; CHECK-NEXT: ret i128 [[XOR]]
;
%bc = bitcast ppc_fp128 %x to i128
diff --git a/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll b/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll
index 8b245bdd79299..a0894c3febc94 100644
--- a/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll
+++ b/llvm/test/Transforms/InstCombine/fneg-fabs-as-int.ll
@@ -317,8 +317,9 @@ define i128 @fneg_fabs_as_int_ppc_fp128_f64_mask(ppc_fp128 %x) {
define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask(ppc_fp128 %x) {
; CHECK-LABEL: define i128 @fneg_fabs_as_int_ppc_fp128_f128_mask
; CHECK-SAME: (ppc_fp128 [[X:%.*]]) {
-; CHECK-NEXT: [[BC:%.*]] = bitcast ppc_fp128 [[X]] to i128
-; CHECK-NEXT: [[OR:%.*]] = or i128 [[BC]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[TMP1:%.*]] = call ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 [[X]])
+; CHECK-NEXT: [[TMP2:%.*]] = fneg ppc_fp128 [[TMP1]]
+; CHECK-NEXT: [[OR:%.*]] = bitcast ppc_fp128 [[TMP2]] to i128
; CHECK-NEXT: ret i128 [[OR]]
;
%bc = bitcast ppc_fp128 %x to i128
diff --git a/llvm/unittests/SandboxIR/TypesTest.cpp b/llvm/unittests/SandboxIR/TypesTest.cpp
index d87f034bd047e..880caa7137a44 100644
--- a/llvm/unittests/SandboxIR/TypesTest.cpp
+++ b/llvm/unittests/SandboxIR/TypesTest.cpp
@@ -180,8 +180,8 @@ define void @foo(i32 %v0) {
EXPECT_EQ(VecTy32x2->getScalarSizeInBits(), 32u);
// Check getFPMantissaWidth().
EXPECT_EQ(FloatTy->getFPMantissaWidth(), LLVMFloatTy->getFPMantissaWidth());
- // Check isIEEE().
- EXPECT_EQ(FloatTy->isIEEE(), LLVMFloatTy->isIEEE());
+ // Check isIEEELikeFPTy().
+ EXPECT_EQ(FloatTy->isIEEELikeFPTy(), LLVMFloatTy->isIEEELikeFPTy());
// Check getScalarType().
EXPECT_EQ(
Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8u))->getScalarType(),
``````````
</details>
https://github.com/llvm/llvm-project/pull/130496
More information about the llvm-commits
mailing list