Skip to content

Commit 225ae82

Browse files
authored
[InstCombine] fold cond ? x : -x == 0 into x == 0 (#85673)
Resolve #85250 Alive2: https://alive2.llvm.org/ce/z/7DMRCy
1 parent 22bf7c5 commit 225ae82

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -8045,6 +8045,14 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
80458045
Constant *RHSC;
80468046
if (match(Op0, m_Instruction(LHSI)) && match(Op1, m_Constant(RHSC))) {
80478047
switch (LHSI->getOpcode()) {
8048+
case Instruction::Select:
8049+
// fcmp eq (cond ? x : -x), 0 --> fcmp eq x, 0
8050+
if (FCmpInst::isEquality(Pred) && match(RHSC, m_AnyZeroFP()) &&
8051+
(match(LHSI,
8052+
m_Select(m_Value(), m_Value(X), m_FNeg(m_Deferred(X)))) ||
8053+
match(LHSI, m_Select(m_Value(), m_FNeg(m_Value(X)), m_Deferred(X)))))
8054+
return replaceOperand(I, 0, X);
8055+
break;
80488056
case Instruction::PHI:
80498057
if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI)))
80508058
return NV;

llvm/test/Transforms/InstCombine/fcmp.ll

+232
Original file line numberDiff line numberDiff line change
@@ -1486,3 +1486,235 @@ define i1 @fcmp_fadd_fast_zero(float %x, float %y) {
14861486
%cmp = fcmp ugt float %add, %y
14871487
ret i1 %cmp
14881488
}
1489+
1490+
define i1 @fcmp_ueq_sel_x_negx(float %x) {
1491+
; CHECK-LABEL: @fcmp_ueq_sel_x_negx(
1492+
; CHECK-NEXT: [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
1493+
; CHECK-NEXT: ret i1 [[RES]]
1494+
;
1495+
%f = fcmp ueq float %x, 0.000000e+00
1496+
%neg = fneg float %x
1497+
%sel = select i1 %f, float %x, float %neg
1498+
%res = fcmp ueq float %sel, 0.000000e+00
1499+
ret i1 %res
1500+
}
1501+
1502+
define i1 @fcmp_une_sel_x_negx(float %x) {
1503+
; CHECK-LABEL: @fcmp_une_sel_x_negx(
1504+
; CHECK-NEXT: [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
1505+
; CHECK-NEXT: ret i1 [[RES]]
1506+
;
1507+
%f = fcmp une float %x, 0.000000e+00
1508+
%neg = fneg float %x
1509+
%sel = select i1 %f, float %x, float %neg
1510+
%res = fcmp une float %sel, 0.000000e+00
1511+
ret i1 %res
1512+
}
1513+
1514+
define i1 @fcmp_oeq_sel_x_negx(float %x) {
1515+
; CHECK-LABEL: @fcmp_oeq_sel_x_negx(
1516+
; CHECK-NEXT: [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
1517+
; CHECK-NEXT: ret i1 [[RES]]
1518+
;
1519+
%f = fcmp oeq float %x, 0.000000e+00
1520+
%neg = fneg float %x
1521+
%sel = select i1 %f, float %x, float %neg
1522+
%res = fcmp oeq float %sel, 0.000000e+00
1523+
ret i1 %res
1524+
}
1525+
1526+
define i1 @fcmp_one_sel_x_negx(float %x) {
1527+
; CHECK-LABEL: @fcmp_one_sel_x_negx(
1528+
; CHECK-NEXT: [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
1529+
; CHECK-NEXT: ret i1 [[RES]]
1530+
;
1531+
%f = fcmp one float %x, 0.000000e+00
1532+
%neg = fneg float %x
1533+
%sel = select i1 %f, float %x, float %neg
1534+
%res = fcmp one float %sel, 0.000000e+00
1535+
ret i1 %res
1536+
}
1537+
1538+
define i1 @fcmp_ueq_sel_x_negx_nzero(float %x) {
1539+
; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero(
1540+
; CHECK-NEXT: [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
1541+
; CHECK-NEXT: ret i1 [[RES]]
1542+
;
1543+
%f = fcmp ueq float %x, 0.000000e+00
1544+
%neg = fneg float %x
1545+
%sel = select i1 %f, float %x, float %neg
1546+
%res = fcmp ueq float %sel, -0.000000e+00
1547+
ret i1 %res
1548+
}
1549+
1550+
define i1 @fcmp_une_sel_x_negx_nzero(float %x) {
1551+
; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero(
1552+
; CHECK-NEXT: [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
1553+
; CHECK-NEXT: ret i1 [[RES]]
1554+
;
1555+
%f = fcmp une float %x, 0.000000e+00
1556+
%neg = fneg float %x
1557+
%sel = select i1 %f, float %x, float %neg
1558+
%res = fcmp une float %sel, -0.000000e+00
1559+
ret i1 %res
1560+
}
1561+
1562+
define i1 @fcmp_oeq_sel_x_negx_nzero(float %x) {
1563+
; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero(
1564+
; CHECK-NEXT: [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
1565+
; CHECK-NEXT: ret i1 [[RES]]
1566+
;
1567+
%f = fcmp oeq float %x, 0.000000e+00
1568+
%neg = fneg float %x
1569+
%sel = select i1 %f, float %x, float %neg
1570+
%res = fcmp oeq float %sel, -0.000000e+00
1571+
ret i1 %res
1572+
}
1573+
1574+
define i1 @fcmp_one_sel_x_negx_nzero(float %x) {
1575+
; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero(
1576+
; CHECK-NEXT: [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
1577+
; CHECK-NEXT: ret i1 [[RES]]
1578+
;
1579+
%f = fcmp one float %x, 0.000000e+00
1580+
%neg = fneg float %x
1581+
%sel = select i1 %f, float %x, float %neg
1582+
%res = fcmp one float %sel, -0.000000e+00
1583+
ret i1 %res
1584+
}
1585+
1586+
define <8 x i1> @fcmp_ueq_sel_x_negx_vec(<8 x float> %x) {
1587+
; CHECK-LABEL: @fcmp_ueq_sel_x_negx_vec(
1588+
; CHECK-NEXT: [[RES:%.*]] = fcmp ueq <8 x float> [[X:%.*]], zeroinitializer
1589+
; CHECK-NEXT: ret <8 x i1> [[RES]]
1590+
;
1591+
%f = fcmp ueq <8 x float> %x, zeroinitializer
1592+
%neg = fneg <8 x float> %x
1593+
%sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1594+
%res = fcmp ueq <8 x float> %sel, zeroinitializer
1595+
ret <8 x i1> %res
1596+
}
1597+
1598+
define <8 x i1> @fcmp_une_sel_x_negx_vec(<8 x float> %x) {
1599+
; CHECK-LABEL: @fcmp_une_sel_x_negx_vec(
1600+
; CHECK-NEXT: [[RES:%.*]] = fcmp une <8 x float> [[X:%.*]], zeroinitializer
1601+
; CHECK-NEXT: ret <8 x i1> [[RES]]
1602+
;
1603+
%f = fcmp une <8 x float> %x, zeroinitializer
1604+
%neg = fneg <8 x float> %x
1605+
%sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1606+
%res = fcmp une <8 x float> %sel, zeroinitializer
1607+
ret <8 x i1> %res
1608+
}
1609+
1610+
define <8 x i1> @fcmp_oeq_sel_x_negx_vec(<8 x float> %x) {
1611+
; CHECK-LABEL: @fcmp_oeq_sel_x_negx_vec(
1612+
; CHECK-NEXT: [[RES:%.*]] = fcmp oeq <8 x float> [[X:%.*]], zeroinitializer
1613+
; CHECK-NEXT: ret <8 x i1> [[RES]]
1614+
;
1615+
%f = fcmp oeq <8 x float> %x, zeroinitializer
1616+
%neg = fneg <8 x float> %x
1617+
%sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1618+
%res = fcmp oeq <8 x float> %sel, zeroinitializer
1619+
ret <8 x i1> %res
1620+
}
1621+
1622+
define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
1623+
; CHECK-LABEL: @fcmp_one_sel_x_negx_vec(
1624+
; CHECK-NEXT: [[RES:%.*]] = fcmp one <8 x float> [[X:%.*]], zeroinitializer
1625+
; CHECK-NEXT: ret <8 x i1> [[RES]]
1626+
;
1627+
%f = fcmp one <8 x float> %x, zeroinitializer
1628+
%neg = fneg <8 x float> %x
1629+
%sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
1630+
%res = fcmp one <8 x float> %sel, zeroinitializer
1631+
ret <8 x i1> %res
1632+
}
1633+
1634+
define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1635+
; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(
1636+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf oeq <2 x float> [[X:%.*]], zeroinitializer
1637+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1638+
;
1639+
%fneg = fneg <2 x float> %x
1640+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1641+
%icmp = fcmp ninf oeq <2 x float> %sel, <float 0.0, float -0.0>
1642+
ret <2 x i1> %icmp
1643+
}
1644+
1645+
define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1646+
; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(
1647+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf one <2 x float> [[X:%.*]], zeroinitializer
1648+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1649+
;
1650+
%fneg = fneg <2 x float> %x
1651+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1652+
%icmp = fcmp ninf one <2 x float> %sel, <float 0.0, float -0.0>
1653+
ret <2 x i1> %icmp
1654+
}
1655+
1656+
define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1657+
; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(
1658+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf ueq <2 x float> [[X:%.*]], zeroinitializer
1659+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1660+
;
1661+
%fneg = fneg <2 x float> %x
1662+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1663+
%icmp = fcmp ninf ueq <2 x float> %sel, <float 0.0, float -0.0>
1664+
ret <2 x i1> %icmp
1665+
}
1666+
1667+
define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
1668+
; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(
1669+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp ninf une <2 x float> [[X:%.*]], zeroinitializer
1670+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1671+
;
1672+
%fneg = fneg <2 x float> %x
1673+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1674+
%icmp = fcmp ninf une <2 x float> %sel, <float 0.0, float -0.0>
1675+
ret <2 x i1> %icmp
1676+
}
1677+
1678+
define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1679+
; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(
1680+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan oeq <2 x float> [[X:%.*]], zeroinitializer
1681+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1682+
;
1683+
%fneg = fneg <2 x float> %x
1684+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1685+
%icmp = fcmp nnan oeq <2 x float> %sel, <float 0.0, float -0.0>
1686+
ret <2 x i1> %icmp
1687+
}
1688+
1689+
define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1690+
; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(
1691+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan one <2 x float> [[X:%.*]], zeroinitializer
1692+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1693+
;
1694+
%fneg = fneg <2 x float> %x
1695+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1696+
%icmp = fcmp nnan one <2 x float> %sel, <float 0.0, float -0.0>
1697+
ret <2 x i1> %icmp
1698+
}
1699+
1700+
define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1701+
; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(
1702+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan ueq <2 x float> [[X:%.*]], zeroinitializer
1703+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1704+
;
1705+
%fneg = fneg <2 x float> %x
1706+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1707+
%icmp = fcmp nnan ueq <2 x float> %sel, <float 0.0, float -0.0>
1708+
ret <2 x i1> %icmp
1709+
}
1710+
1711+
define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
1712+
; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(
1713+
; CHECK-NEXT: [[ICMP:%.*]] = fcmp nnan une <2 x float> [[X:%.*]], zeroinitializer
1714+
; CHECK-NEXT: ret <2 x i1> [[ICMP]]
1715+
;
1716+
%fneg = fneg <2 x float> %x
1717+
%sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
1718+
%icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0>
1719+
ret <2 x i1> %icmp
1720+
}

0 commit comments

Comments
 (0)