|
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"
|
@@ -4212,6 +4213,53 @@ SDValue TargetLowering::foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
|
4212 | 4213 | return SDValue();
|
4213 | 4214 | }
|
4214 | 4215 |
|
| 4216 | +/// This helper function of SimplifySetCC tries to optimize the comparison when |
| 4217 | +/// either operand of the SetCC node is a bitwise-or instruction. |
| 4218 | +/// For now, this just transforms (X | Y) ==/!= Y into X & ~Y ==/!= 0. |
| 4219 | +SDValue TargetLowering::foldSetCCWithOr(EVT VT, SDValue N0, SDValue N1, |
| 4220 | + ISD::CondCode Cond, const SDLoc &DL, |
| 4221 | + DAGCombinerInfo &DCI) const { |
| 4222 | + if (N1.getOpcode() == ISD::OR && N0.getOpcode() != ISD::OR) |
| 4223 | + std::swap(N0, N1); |
| 4224 | + |
| 4225 | + SelectionDAG &DAG = DCI.DAG; |
| 4226 | + EVT OpVT = N0.getValueType(); |
| 4227 | + if (!N0.hasOneUse() || !OpVT.isInteger() || |
| 4228 | + (Cond != ISD::SETEQ && Cond != ISD::SETNE)) |
| 4229 | + return SDValue(); |
| 4230 | + |
| 4231 | + // Match these patterns in any of their permutations. |
| 4232 | + // (X | Y) == Y |
| 4233 | + // (X | Y) != Y |
| 4234 | + SDValue X, Y; |
| 4235 | + if (N0.getOperand(0) == N1) { |
| 4236 | + X = N0.getOperand(1); |
| 4237 | + Y = N0.getOperand(0); |
| 4238 | + } else if (N0.getOperand(1) == N1) { |
| 4239 | + X = N0.getOperand(0); |
| 4240 | + Y = N0.getOperand(1); |
| 4241 | + } else { |
| 4242 | + return SDValue(); |
| 4243 | + } |
| 4244 | + |
| 4245 | + if (hasAndNotCompare(Y)) { |
| 4246 | + // If the target supports an 'and-not' or 'and-complement' logic operation, |
| 4247 | + // try to use that to make a comparison operation more efficient. |
| 4248 | + |
| 4249 | + // Bail out if the compare operand that we want to turn into a zero is |
| 4250 | + // already a zero (otherwise, infinite loop). |
| 4251 | + if (isNullConstant(Y)) |
| 4252 | + return SDValue(); |
| 4253 | + |
| 4254 | + // Transform this into: X & ~Y == 0. |
| 4255 | + SDValue NotY = DAG.getNOT(SDLoc(Y), Y, OpVT); |
| 4256 | + SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, X, NotY); |
| 4257 | + return DAG.getSetCC(DL, VT, NewAnd, DAG.getConstant(0, DL, OpVT), Cond); |
| 4258 | + } |
| 4259 | + |
| 4260 | + return SDValue(); |
| 4261 | +} |
| 4262 | + |
4215 | 4263 | /// There are multiple IR patterns that could be checking whether certain
|
4216 | 4264 | /// truncation of a signed number would be lossy or not. The pattern which is
|
4217 | 4265 | /// best at IR level, may not lower optimally. Thus, we want to unfold it.
|
@@ -5507,6 +5555,9 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
5507 | 5555 |
|
5508 | 5556 | if (SDValue V = foldSetCCWithAnd(VT, N0, N1, Cond, dl, DCI))
|
5509 | 5557 | return V;
|
| 5558 | + |
| 5559 | + if (SDValue V = foldSetCCWithOr(VT, N0, N1, Cond, dl, DCI)) |
| 5560 | + return V; |
5510 | 5561 | }
|
5511 | 5562 |
|
5512 | 5563 | // Fold remainder of division by a constant.
|
|
0 commit comments