mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[InstCombine] loosen FP 0.0 constraint for fcmp+select substitution
It looks like we correctly removed edge cases with 0.0 from D50714, but we were a bit conservative because getBinOpIdentity() doesn't distinguish between +0.0 and -0.0 and 'nsz' is effectively always true for fcmp (see discussion in: https://bugs.llvm.org/show_bug.cgi?id=38086 Without this change, we would get regressions by canonicalizing to +0.0 in all fcmp, and that's a step towards solving: https://bugs.llvm.org/show_bug.cgi?id=39475 llvm-svn: 346143
This commit is contained in:
parent
8b43ef1240
commit
51ca26e748
@ -75,13 +75,22 @@ static Instruction *foldSelectBinOpIdentity(SelectInst &Sel,
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
// A select operand must be a binop, and the compare constant must be the
|
||||
// identity constant for that binop.
|
||||
// A select operand must be a binop.
|
||||
BinaryOperator *BO;
|
||||
if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)) ||
|
||||
ConstantExpr::getBinOpIdentity(BO->getOpcode(), BO->getType(), true) != C)
|
||||
if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)))
|
||||
return nullptr;
|
||||
|
||||
// The compare constant must be the identity constant for that binop.
|
||||
// If this a floating-point compare with 0.0, any zero constant will do.
|
||||
Type *Ty = BO->getType();
|
||||
Constant *IdC = ConstantExpr::getBinOpIdentity(BO->getOpcode(), Ty, true);
|
||||
if (IdC != C) {
|
||||
if (!IdC || !CmpInst::isFPPredicate(Pred))
|
||||
return nullptr;
|
||||
if (!match(IdC, m_AnyZeroFP()) || !match(C, m_AnyZeroFP()))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Last, match the compare variable operand with a binop operand.
|
||||
Value *Y;
|
||||
if (!BO->isCommutative() && !match(BO, m_BinOp(m_Value(Y), m_Specific(X))))
|
||||
|
@ -152,13 +152,12 @@ define float @select_fadd_fcmp(float %x, float %y, float %z) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fadd_fcmp_poszero(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @select_fadd_fcmp_poszero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp oeq float %x, 0.0
|
||||
@ -181,14 +180,13 @@ define float @select_fadd_fcmp_2(float %x, float %y, float %v) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fadd_fcmp_2_poszero(float %x, float %y, float %v) {
|
||||
; CHECK-LABEL: @select_fadd_fcmp_2_poszero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z]]
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp une float %x, 0.0
|
||||
@ -210,13 +208,12 @@ define float @select_fadd_fcmp_3(float %x, float %y) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fadd_fcmp_3_poszero(float %x, float %y) {
|
||||
; CHECK-LABEL: @select_fadd_fcmp_3_poszero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], 6.000000e+00
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float 6.000000e+00
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp une float %x, 0.0
|
||||
@ -237,13 +234,12 @@ define float @select_fadd_fcmp_4(float %x, float %y, float %z) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fadd_fcmp_4_poszero(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @select_fadd_fcmp_4_poszero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fadd nsz float [[Z:%.*]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[B]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Y:%.*]], float [[Z:%.*]]
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp une float %x, 0.0
|
||||
@ -266,14 +262,13 @@ define float @select_fadd_fcmp_5(float %x, float %y, float %v) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fadd_fcmp_5_poszero(float %x, float %y, float %v) {
|
||||
; CHECK-LABEL: @select_fadd_fcmp_5_poszero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[Z:%.*]] = fadd float [[V:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fadd float [[Z]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp oeq float %x, 0.0
|
||||
@ -295,13 +290,12 @@ define float @select_fadd_fcmp_6(float %x, float %y, float %z) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fadd_fcmp_6_poszero(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @select_fadd_fcmp_6_poszero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fadd float [[X]], 6.000000e+00
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float 6.000000e+00, float [[Y:%.*]]
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp oeq float %x, 0.0
|
||||
@ -334,13 +328,12 @@ define float @select_fsub_fcmp(float %x, float %y, float %z) {
|
||||
ret float %C
|
||||
}
|
||||
|
||||
; TODO: This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
; This is logically equivalent to the previous test - fcmp ignores the sign of 0.0.
|
||||
|
||||
define float @select_fsub_fcmp_negzero(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @select_fsub_fcmp_negzero(
|
||||
; CHECK-NEXT: [[A:%.*]] = fcmp oeq float [[X:%.*]], -0.000000e+00
|
||||
; CHECK-NEXT: [[B:%.*]] = fsub nsz float [[Z:%.*]], [[X]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[B]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], float [[Z:%.*]], float [[Y:%.*]]
|
||||
; CHECK-NEXT: ret float [[C]]
|
||||
;
|
||||
%A = fcmp oeq float %x, -0.0
|
||||
|
Loading…
Reference in New Issue
Block a user