[llvm] r281354 - [DAGCombiner] Use APInt directly in (shl (ext (shl x, c1)), c2) combine

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 13 10:15:28 PDT 2016


Author: rksimon
Date: Tue Sep 13 12:15:28 2016
New Revision: 281354

URL: http://llvm.org/viewvc/llvm-project?rev=281354&view=rev
Log:
[DAGCombiner] Use APInt directly in (shl (ext (shl x, c1)), c2) combine

Fix failure to detect out of range shift constants leading to assert in ConstantSDNode::getZExtValue()

Followup to D23007

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/test/CodeGen/X86/shift-i128.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=281354&r1=281353&r2=281354&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Sep 13 12:15:28 2016
@@ -4518,18 +4518,22 @@ SDValue DAGCombiner::visitSHL(SDNode *N)
       N0.getOperand(0).getOpcode() == ISD::SHL) {
     SDValue N0Op0 = N0.getOperand(0);
     if (ConstantSDNode *N0Op0C1 = isConstOrConstSplat(N0Op0.getOperand(1))) {
-      uint64_t c1 = N0Op0C1->getZExtValue();
-      uint64_t c2 = N1C->getZExtValue();
+      APInt c1 = N0Op0C1->getAPIntValue();
+      APInt c2 = N1C->getAPIntValue();
+      zeroExtendToMatch(c1, c2, 1 /* Overflow Bit */);
+
       EVT InnerShiftVT = N0Op0.getValueType();
       uint64_t InnerShiftSize = InnerShiftVT.getScalarSizeInBits();
-      if (c2 >= OpSizeInBits - InnerShiftSize) {
+      if (c2.uge(OpSizeInBits - InnerShiftSize)) {
         SDLoc DL(N0);
-        if (c1 + c2 >= OpSizeInBits)
+        APInt Sum = c1 + c2;
+        if (Sum.uge(OpSizeInBits))
           return DAG.getConstant(0, DL, VT);
-        return DAG.getNode(ISD::SHL, DL, VT,
-                           DAG.getNode(N0.getOpcode(), DL, VT,
-                                       N0Op0->getOperand(0)),
-                           DAG.getConstant(c1 + c2, DL, N1.getValueType()));
+
+        return DAG.getNode(
+            ISD::SHL, DL, VT,
+            DAG.getNode(N0.getOpcode(), DL, VT, N0Op0->getOperand(0)),
+            DAG.getConstant(Sum.getZExtValue(), DL, N1.getValueType()));
       }
     }
   }
@@ -5264,11 +5268,11 @@ SDValue DAGCombiner::visitSELECT(SDNode
     if (N0->getOpcode() == ISD::XOR) {
       if (auto *C = dyn_cast<ConstantSDNode>(N0->getOperand(1))) {
         SDValue Cond0 = N0->getOperand(0);
-        if (C->isOne()) 
-          return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(), 
+        if (C->isOne())
+          return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(),
                              Cond0, N2, N1);
         else
-          return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(), 
+          return DAG.getNode(ISD::SELECT, SDLoc(N), N1.getValueType(),
                              Cond0, N1, N2);
       }
     }

Modified: llvm/trunk/test/CodeGen/X86/shift-i128.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shift-i128.ll?rev=281354&r1=281353&r2=281354&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/shift-i128.ll (original)
+++ llvm/trunk/test/CodeGen/X86/shift-i128.ll Tue Sep 13 12:15:28 2016
@@ -116,3 +116,21 @@ entry:
 	store <2 x i128> %1, <2 x i128>* %r, align 16
 	ret void
 }
+
+;
+; Combines
+;
+
+define <2 x i256> @shl_sext_shl_outofrange(<2 x i128> %a0) {
+  %1 = shl <2 x i128> %a0, <i128 -1, i128 -1>
+  %2 = sext <2 x i128> %1 to <2 x i256>
+  %3 = shl <2 x i256> %2, <i256 128, i256 128>
+  ret <2 x i256> %3
+}
+
+define <2 x i256> @shl_zext_shl_outofrange(<2 x i128> %a0) {
+  %1 = shl <2 x i128> %a0, <i128 -1, i128 -1>
+  %2 = zext <2 x i128> %1 to <2 x i256>
+  %3 = shl <2 x i256> %2, <i256 128, i256 128>
+  ret <2 x i256> %3
+}




More information about the llvm-commits mailing list