MCPcopy Create free account
hub / github.com/AliveToolkit/alive2 / optimize_ptrcmp

Function optimize_ptrcmp

tools/transform.cpp:1669–1727  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1667}
1668
1669static void optimize_ptrcmp(Function &f) {
1670 auto is_inbounds = [](const Value &v) {
1671 if (auto *gep = dynamic_cast<const GEP*>(&v)) {
1672 if (!gep->isInBounds())
1673 return false;
1674
1675 // ptr only in bounds if some idx is non-zero
1676 for (auto &[sz, idx] : gep->getIdxs()) {
1677 auto n = getInt(*idx);
1678 if (sz != 0 && n.value_or(0) != 0)
1679 return true;
1680 }
1681 return false;
1682 }
1683
1684 if (!returns_local(v))
1685 return false;
1686
1687 if (auto *call = dynamic_cast<const FnCall*>(&v)) {
1688 auto &attrs = call->getAttributes();
1689 if (attrs.derefBytes > 0 || attrs.derefOrNullBytes > 0)
1690 return true;
1691 return false;
1692 }
1693 return true;
1694 };
1695
1696 for (auto &i : f.instrs()) {
1697 auto *icmp = dynamic_cast<const ICmp*>(&i);
1698 if (!icmp)
1699 continue;
1700
1701 auto cond = icmp->getCond();
1702 bool is_eq = cond == ICmp::EQ || cond == ICmp::NE;
1703 bool is_signed_cmp = cond == ICmp::SLE || cond == ICmp::SLT ||
1704 cond == ICmp::SGE || cond == ICmp::SGT;
1705
1706 auto ops = icmp->operands();
1707 auto *op0 = ops[0];
1708 auto *op1 = ops[1];
1709 if (is_eq &&
1710 ((is_inbounds(*op0) && dynamic_cast<const NullPointerValue*>(op1)) ||
1711 (is_inbounds(*op1) && dynamic_cast<const NullPointerValue*>(op0)))) {
1712 // (gep inbounds p, ofs) == null
1713 const_cast<ICmp*>(icmp)->setPtrCmpMode(ICmp::PROVENANCE);
1714 }
1715
1716 auto base0 = get_base_ptr(op0);
1717 auto base1 = get_base_ptr(op1);
1718 if (base0 && base0 == base1) {
1719 if (is_eq ||
1720 (is_inbounds(*op0) && is_inbounds(*op1) && !is_signed_cmp))
1721 // Even if op0 and op1 are inbounds, 'icmp slt op0, op1' must
1722 // compare underlying addresses because it is possible for the block
1723 // to span across [a, b] where a >s 0 && b <s 0.
1724 const_cast<ICmp*>(icmp)->setPtrCmpMode(ICmp::OFFSETONLY);
1725 }
1726 }

Callers 1

preprocessMethod · 0.85

Calls 8

getIntFunction · 0.85
returns_localFunction · 0.85
get_base_ptrFunction · 0.85
isInBoundsMethod · 0.80
setPtrCmpModeMethod · 0.80
instrsMethod · 0.45
getCondMethod · 0.45
operandsMethod · 0.45

Tested by

no test coverage detected