|
21 | 21 | #include "llvm/CodeGen/MachineFunction.h"
|
22 | 22 | #include "llvm/CodeGen/MachineJumpTableInfo.h"
|
23 | 23 | #include "llvm/CodeGen/MachineRegisterInfo.h"
|
| 24 | +#include "llvm/CodeGen/SDPatternMatch.h" |
24 | 25 | #include "llvm/CodeGen/SelectionDAG.h"
|
25 | 26 | #include "llvm/CodeGen/TargetRegisterInfo.h"
|
26 | 27 | #include "llvm/IR/DataLayout.h"
|
|
37 | 38 | #include <cctype>
|
38 | 39 | #include <deque>
|
39 | 40 | using namespace llvm;
|
| 41 | +using namespace llvm::SDPatternMatch; |
40 | 42 |
|
41 | 43 | /// NOTE: The TargetMachine owns TLOF.
|
42 | 44 | TargetLowering::TargetLowering(const TargetMachine &tm)
|
@@ -4212,6 +4214,42 @@ SDValue TargetLowering::foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
|
4212 | 4214 | return SDValue();
|
4213 | 4215 | }
|
4214 | 4216 |
|
| 4217 | +/// This helper function of SimplifySetCC tries to optimize the comparison when |
| 4218 | +/// either operand of the SetCC node is a bitwise-or instruction. |
| 4219 | +/// For now, this just transforms (X | Y) ==/!= Y into X & ~Y ==/!= 0. |
| 4220 | +SDValue TargetLowering::foldSetCCWithOr(EVT VT, SDValue N0, SDValue N1, |
| 4221 | + ISD::CondCode Cond, const SDLoc &DL, |
| 4222 | + DAGCombinerInfo &DCI) const { |
| 4223 | + if (N1.getOpcode() == ISD::OR && N0.getOpcode() != ISD::OR) |
| 4224 | + std::swap(N0, N1); |
| 4225 | + |
| 4226 | + SelectionDAG &DAG = DCI.DAG; |
| 4227 | + EVT OpVT = N0.getValueType(); |
| 4228 | + if (!N0.hasOneUse() || !OpVT.isInteger() || |
| 4229 | + (Cond != ISD::SETEQ && Cond != ISD::SETNE)) |
| 4230 | + return SDValue(); |
| 4231 | + |
| 4232 | + // (X | Y) == Y |
| 4233 | + // (X | Y) != Y |
| 4234 | + SDValue X; |
| 4235 | + if (sd_match(N0, m_Or(m_Value(X), m_Specific(N1))) && hasAndNotCompare(N1)) { |
| 4236 | + // If the target supports an 'and-not' or 'and-complement' logic operation, |
| 4237 | + // try to use that to make a comparison operation more efficient. |
| 4238 | + |
| 4239 | + // Bail out if the compare operand that we want to turn into a zero is |
| 4240 | + // already a zero (otherwise, infinite loop). |
| 4241 | + if (isNullConstant(N1)) |
| 4242 | + return SDValue(); |
| 4243 | + |
| 4244 | + // Transform this into: X & ~Y ==/!= 0. |
| 4245 | + SDValue NotY = DAG.getNOT(SDLoc(N1), N1, OpVT); |
| 4246 | + SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, X, NotY); |
| 4247 | + return DAG.getSetCC(DL, VT, NewAnd, DAG.getConstant(0, DL, OpVT), Cond); |
| 4248 | + } |
| 4249 | + |
| 4250 | + return SDValue(); |
| 4251 | +} |
| 4252 | + |
4215 | 4253 | /// There are multiple IR patterns that could be checking whether certain
|
4216 | 4254 | /// truncation of a signed number would be lossy or not. The pattern which is
|
4217 | 4255 | /// best at IR level, may not lower optimally. Thus, we want to unfold it.
|
@@ -5507,6 +5545,9 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
5507 | 5545 |
|
5508 | 5546 | if (SDValue V = foldSetCCWithAnd(VT, N0, N1, Cond, dl, DCI))
|
5509 | 5547 | return V;
|
| 5548 | + |
| 5549 | + if (SDValue V = foldSetCCWithOr(VT, N0, N1, Cond, dl, DCI)) |
| 5550 | + return V; |
5510 | 5551 | }
|
5511 | 5552 |
|
5512 | 5553 | // Fold remainder of division by a constant.
|
|
0 commit comments