-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[InstCombine] Fold fneg/fabs patterns with ppc_f128 #130557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-adt @llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesThis patch is needed by #130496. Full diff: https://github.com/llvm/llvm-project/pull/130557.diff 4 Files Affected:
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
|
// 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()) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth wrapping this in a predicate with this explicit property
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding new matchers like m_IntValue/m_FPValue
? They are very useful to work with the bitcast matcher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arsenm Do you mean the property "has sign bit in high bit"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
fltNanEncoding::AllOnes, | ||
false, | ||
false, | ||
false}; |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. All the bits are exponent bits (E8M0). It ranges from 2^-127 to 2^127 (255 values). The remaining one is NaN (all ones).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooops, it looks like I looked at a different entry, not sure how I ended up there. This one is:
// 8-bit floating point number with (all the) 8 bits for the exponent
// like in FP32. There are no zeroes, no infinities, and no denormal values.
// This format has unsigned representation only. (U -> Unsigned only).
// NaN is represented with all bits set to 1. Bias is 127.
// This format represents the scale data type in the MX specification from:
// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
Okay, that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes me wonder though whether we need a separate flag. Can we use hasSignedRepr instead, and specify that hasSignedRepr must have the sign bit in the MSB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC hasSignedRepr is weaker. It just indicates that the semantics doesn't have negative numbers
.
29eaf37
to
dde7d59
Compare
Ping. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This patch is needed by llvm#130496.
This patch is needed by #130496.