summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-11-29 20:58:26 +0000
committerSanjay Patel <spatel@rotateright.com>2018-11-29 20:58:26 +0000
commit8d271442514409323d899908553c290d1c3faba4 (patch)
tree4b191ffa0a28fbffae7c844f02d5844dfb80f700 /llvm/lib/CodeGen
parentc1410635bfa8979862606056b5fc1eb5db4840e5 (diff)
downloadbcm5719-llvm-8d271442514409323d899908553c290d1c3faba4.tar.gz
bcm5719-llvm-8d271442514409323d899908553c290d1c3faba4.zip
[DAGCombiner] narrow truncated binops
The motivating case for this is shown in: https://bugs.llvm.org/show_bug.cgi?id=32023 and the corresponding rot16.ll regression tests. Because x86 scalar shift amounts are i8 values, we can end up with trunc-binop-trunc sequences that don't get folded in IR. As the TODO comments suggest, there will be regressions if we extend this (for x86, we mostly seem to be missing LEA opportunities, but there are likely vector folds missing too). I think those should be considered existing bugs because this is the same transform that we do as an IR canonicalization in instcombine. We just need more tests to make those visible independent of this patch. Differential Revision: https://reviews.llvm.org/D54640 llvm-svn: 347917
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index db9a1048876..61c833043fa 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9722,6 +9722,28 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
if (SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
return NewVSel;
+ // Narrow a suitable binary operation with a constant operand by moving it
+ // ahead of the truncate. This is limited to pre-legalization because targets
+ // may prefer a wider type during later combines and invert this transform.
+ switch (N0.getOpcode()) {
+ // TODO: Add case for ADD - that will likely require a change in logic here
+ // or target-specific changes to avoid regressions.
+ case ISD::SUB:
+ case ISD::MUL:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ // TODO: This should allow vector constants/types too.
+ if (!LegalOperations && N0.hasOneUse() &&
+ (isa<ConstantSDNode>(N0.getOperand(0)) ||
+ isa<ConstantSDNode>(N0.getOperand(1)))) {
+ SDLoc DL(N);
+ SDValue NarrowL = DAG.getNode(ISD::TRUNCATE, DL, VT, N0.getOperand(0));
+ SDValue NarrowR = DAG.getNode(ISD::TRUNCATE, DL, VT, N0.getOperand(1));
+ return DAG.getNode(N0.getOpcode(), DL, VT, NarrowL, NarrowR);
+ }
+ }
+
return SDValue();
}
OpenPOWER on IntegriCloud