forked from OSchip/llvm-project
				
			Reapply 122353-122355 with fixes. 122354 was wrong;
the shift type was needed one place, the shift count type another. The transform in 123555 had the same problem. llvm-svn: 122366
This commit is contained in:
		
							parent
							
								
									5c7aa98886
								
							
						
					
					
						commit
						a94e36bbee
					
				| 
						 | 
					@ -2967,11 +2967,37 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
 | 
				
			||||||
      N0.getOperand(1).getOpcode() == ISD::Constant) {
 | 
					      N0.getOperand(1).getOpcode() == ISD::Constant) {
 | 
				
			||||||
    uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
 | 
					    uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
 | 
				
			||||||
    uint64_t c2 = N1C->getZExtValue();
 | 
					    uint64_t c2 = N1C->getZExtValue();
 | 
				
			||||||
    if (c1 + c2 > OpSizeInBits)
 | 
					    if (c1 + c2 >= OpSizeInBits)
 | 
				
			||||||
      return DAG.getConstant(0, VT);
 | 
					      return DAG.getConstant(0, VT);
 | 
				
			||||||
    return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0),
 | 
					    return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0),
 | 
				
			||||||
                       DAG.getConstant(c1 + c2, N1.getValueType()));
 | 
					                       DAG.getConstant(c1 + c2, N1.getValueType()));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // fold (shl (ext (shl x, c1)), c2) -> (ext (shl x, (add c1, c2)))
 | 
				
			||||||
 | 
					  // For this to be valid, the second form must not preserve any of the bits
 | 
				
			||||||
 | 
					  // that are shifted out by the inner shift in the first form.  This means
 | 
				
			||||||
 | 
					  // the outer shift size must be >= the number of bits added by the ext.
 | 
				
			||||||
 | 
					  // As a corollary, we don't care what kind of ext it is.
 | 
				
			||||||
 | 
					  if (N1C && (N0.getOpcode() == ISD::ZERO_EXTEND ||
 | 
				
			||||||
 | 
					              N0.getOpcode() == ISD::ANY_EXTEND ||
 | 
				
			||||||
 | 
					              N0.getOpcode() == ISD::SIGN_EXTEND) &&
 | 
				
			||||||
 | 
					      N0.getOperand(0).getOpcode() == ISD::SHL &&
 | 
				
			||||||
 | 
					      isa<ConstantSDNode>(N0.getOperand(0)->getOperand(1))) {
 | 
				
			||||||
 | 
					    uint64_t c1 = 
 | 
				
			||||||
 | 
					      cast<ConstantSDNode>(N0.getOperand(0)->getOperand(1))->getZExtValue();
 | 
				
			||||||
 | 
					    uint64_t c2 = N1C->getZExtValue();
 | 
				
			||||||
 | 
					    EVT InnerShiftVT = N0.getOperand(0).getValueType();
 | 
				
			||||||
 | 
					    uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits();
 | 
				
			||||||
 | 
					    if (c2 >= OpSizeInBits - InnerShiftSize) {
 | 
				
			||||||
 | 
					      if (c1 + c2 >= OpSizeInBits)
 | 
				
			||||||
 | 
					        return DAG.getConstant(0, VT);
 | 
				
			||||||
 | 
					      return DAG.getNode(ISD::SHL, N0->getDebugLoc(), VT,
 | 
				
			||||||
 | 
					                         DAG.getNode(N0.getOpcode(), N0->getDebugLoc(), VT,
 | 
				
			||||||
 | 
					                                     N0.getOperand(0)->getOperand(0)),
 | 
				
			||||||
 | 
					                         DAG.getConstant(c1 + c2, N1.getValueType()));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or
 | 
					  // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or
 | 
				
			||||||
  //                               (srl (and x, (shl -1, c1)), (sub c1, c2))
 | 
					  //                               (srl (and x, (shl -1, c1)), (sub c1, c2))
 | 
				
			||||||
  if (N1C && N0.getOpcode() == ISD::SRL &&
 | 
					  if (N1C && N0.getOpcode() == ISD::SRL &&
 | 
				
			||||||
| 
						 | 
					@ -3165,7 +3191,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
 | 
				
			||||||
      N0.getOperand(1).getOpcode() == ISD::Constant) {
 | 
					      N0.getOperand(1).getOpcode() == ISD::Constant) {
 | 
				
			||||||
    uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
 | 
					    uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
 | 
				
			||||||
    uint64_t c2 = N1C->getZExtValue();
 | 
					    uint64_t c2 = N1C->getZExtValue();
 | 
				
			||||||
    if (c1 + c2 > OpSizeInBits)
 | 
					    if (c1 + c2 >= OpSizeInBits)
 | 
				
			||||||
      return DAG.getConstant(0, VT);
 | 
					      return DAG.getConstant(0, VT);
 | 
				
			||||||
    return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0),
 | 
					    return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0),
 | 
				
			||||||
                       DAG.getConstant(c1 + c2, N1.getValueType()));
 | 
					                       DAG.getConstant(c1 + c2, N1.getValueType()));
 | 
				
			||||||
| 
						 | 
					@ -3178,7 +3204,8 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
 | 
				
			||||||
    uint64_t c1 = 
 | 
					    uint64_t c1 = 
 | 
				
			||||||
      cast<ConstantSDNode>(N0.getOperand(0)->getOperand(1))->getZExtValue();
 | 
					      cast<ConstantSDNode>(N0.getOperand(0)->getOperand(1))->getZExtValue();
 | 
				
			||||||
    uint64_t c2 = N1C->getZExtValue();
 | 
					    uint64_t c2 = N1C->getZExtValue();
 | 
				
			||||||
    EVT InnerShiftVT = N0.getOperand(0)->getOperand(1).getValueType();
 | 
					    EVT InnerShiftVT = N0.getOperand(0).getValueType();
 | 
				
			||||||
 | 
					    EVT ShiftCountVT = N0.getOperand(0)->getOperand(1).getValueType();
 | 
				
			||||||
    uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits();
 | 
					    uint64_t InnerShiftSize = InnerShiftVT.getScalarType().getSizeInBits();
 | 
				
			||||||
    // This is only valid if the OpSizeInBits + c1 = size of inner shift.
 | 
					    // This is only valid if the OpSizeInBits + c1 = size of inner shift.
 | 
				
			||||||
    if (c1 + OpSizeInBits == InnerShiftSize) {
 | 
					    if (c1 + OpSizeInBits == InnerShiftSize) {
 | 
				
			||||||
| 
						 | 
					@ -3187,7 +3214,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
 | 
				
			||||||
      return DAG.getNode(ISD::TRUNCATE, N0->getDebugLoc(), VT,
 | 
					      return DAG.getNode(ISD::TRUNCATE, N0->getDebugLoc(), VT,
 | 
				
			||||||
                         DAG.getNode(ISD::SRL, N0->getDebugLoc(), InnerShiftVT, 
 | 
					                         DAG.getNode(ISD::SRL, N0->getDebugLoc(), InnerShiftVT, 
 | 
				
			||||||
                                     N0.getOperand(0)->getOperand(0),
 | 
					                                     N0.getOperand(0)->getOperand(0),
 | 
				
			||||||
                                     DAG.getConstant(c1 + c2, InnerShiftVT)));
 | 
					                                     DAG.getConstant(c1 + c2, ShiftCountVT)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,9 +29,9 @@ entry:
 | 
				
			||||||
  ret i8 %div
 | 
					  ret i8 %div
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; CHECK: test3:
 | 
					; CHECK: test3:
 | 
				
			||||||
; CHECK: imull	$171, %eax, %eax
 | 
					; CHECK: movzbl  8(%esp), %eax
 | 
				
			||||||
; CHECK-NEXT: shrb	%ah
 | 
					; CHECK-NEXT: imull	$171, %eax, %eax
 | 
				
			||||||
; CHECK-NEXT: movzbl	%ah, %eax
 | 
					; CHECK-NEXT: shrl	$9, %eax
 | 
				
			||||||
; CHECK-NEXT: ret
 | 
					; CHECK-NEXT: ret
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
 | 
				
			||||||
 | 
					; Formerly there were two shifts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define i64 @baz(i32 %A) nounwind {
 | 
				
			||||||
 | 
					; CHECK:  shlq  $49, %rax
 | 
				
			||||||
 | 
					        %tmp1 = shl i32 %A, 17
 | 
				
			||||||
 | 
					        %tmp2 = zext i32 %tmp1 to i64
 | 
				
			||||||
 | 
					        %tmp3 = shl i64 %tmp2, 32
 | 
				
			||||||
 | 
					        ret i64 %tmp3
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue