forked from OSchip/llvm-project
Make the canonicalisation on shifts benifit to more case.
1.Fix pessimized case in FIXME. 2.Add tests for it. 3.The canonicalisation on shifts results in different sequence for tests of machine-licm.Correct some check lines. Differential Revision: https://reviews.llvm.org/D27916 llvm-svn: 290410
This commit is contained in:
parent
37c178b6f5
commit
bf6007bd1b
|
@ -4544,16 +4544,20 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, ConstantSDNode *Amt) {
|
|||
ConstantSDNode *BinOpCst = getAsNonOpaqueConstant(LHS->getOperand(1));
|
||||
if (!BinOpCst) return SDValue();
|
||||
|
||||
// FIXME: disable this unless the input to the binop is a shift by a constant.
|
||||
// If it is not a shift, it pessimizes some common cases like:
|
||||
//
|
||||
// void foo(int *X, int i) { X[i & 1235] = 1; }
|
||||
// int bar(int *X, int i) { return X[i & 255]; }
|
||||
// FIXME: disable this unless the input to the binop is a shift by a constant
|
||||
// or is copy/select.Enable this in other cases when figure out it's exactly profitable.
|
||||
SDNode *BinOpLHSVal = LHS->getOperand(0).getNode();
|
||||
if ((BinOpLHSVal->getOpcode() != ISD::SHL &&
|
||||
BinOpLHSVal->getOpcode() != ISD::SRA &&
|
||||
BinOpLHSVal->getOpcode() != ISD::SRL) ||
|
||||
!isa<ConstantSDNode>(BinOpLHSVal->getOperand(1)))
|
||||
bool isShift = BinOpLHSVal->getOpcode() == ISD::SHL ||
|
||||
BinOpLHSVal->getOpcode() == ISD::SRA ||
|
||||
BinOpLHSVal->getOpcode() == ISD::SRL;
|
||||
bool isCopyOrSelect = BinOpLHSVal->getOpcode() == ISD::CopyFromReg ||
|
||||
BinOpLHSVal->getOpcode() == ISD::SELECT;
|
||||
|
||||
if ((!isShift || !isa<ConstantSDNode>(BinOpLHSVal->getOperand(1))) &&
|
||||
!isCopyOrSelect)
|
||||
return SDValue();
|
||||
|
||||
if (isCopyOrSelect && N->hasOneUse())
|
||||
return SDValue();
|
||||
|
||||
EVT VT = N->getValueType(0);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
; RUN: llc -mtriple=armv7-linux-gnueabihf %s -o - | FileCheck %s
|
||||
|
||||
@array = weak global [4 x i32] zeroinitializer
|
||||
|
||||
define i32 @test_lshr_and1(i32 %x) {
|
||||
entry:
|
||||
;CHECK-LABLE: test_lshr_and1:
|
||||
;CHECK: movw r1, :lower16:array
|
||||
;CHECK-NEXT: and r0, r0, #12
|
||||
;CHECK-NEXT: movt r1, :upper16:array
|
||||
;CHECK-NEXT: ldr r0, [r1, r0]
|
||||
;CHECK-NEXT: bx lr
|
||||
%tmp2 = lshr i32 %x, 2
|
||||
%tmp3 = and i32 %tmp2, 3
|
||||
%tmp4 = getelementptr [4 x i32], [4 x i32]* @array, i32 0, i32 %tmp3
|
||||
%tmp5 = load i32, i32* %tmp4, align 4
|
||||
ret i32 %tmp5
|
||||
}
|
||||
define i32 @test_lshr_and2(i32 %x) {
|
||||
entry:
|
||||
;CHECK-LABLE: test_lshr_and2:
|
||||
;CHECK: ubfx r0, r0, #1, #15
|
||||
;CHECK-NEXT: add r0, r0, r0
|
||||
;CHECK-NEXT: bx lr
|
||||
%a = and i32 %x, 65534
|
||||
%b = lshr i32 %a, 1
|
||||
%c = and i32 %x, 65535
|
||||
%d = lshr i32 %c, 1
|
||||
%e = add i32 %b, %d
|
||||
ret i32 %e
|
||||
}
|
|
@ -85,10 +85,9 @@ define zeroext i16 @t3(i8 zeroext %data, i16 zeroext %crc) nounwind readnone {
|
|||
; CHECK-LABEL: t3:
|
||||
bb.nph:
|
||||
; CHECK: bb.nph
|
||||
; CHECK: movw {{(r[0-9])|(lr)}}, #32768
|
||||
; CHECK: movw {{(r[0-9]+)|(lr)}}, #32768
|
||||
; CHECK: movs {{(r[0-9]+)|(lr)}}, #0
|
||||
; CHECK: movw [[REGISTER:(r[0-9]+)|(lr)]], #16386
|
||||
; CHECK: movw {{(r[0-9]+)|(lr)}}, #65534
|
||||
; CHECK: movt {{(r[0-9]+)|(lr)}}, #65535
|
||||
br label %bb
|
||||
|
||||
|
@ -97,7 +96,6 @@ bb: ; preds = %bb, %bb.nph
|
|||
; CHECK: eor.w
|
||||
; CHECK: eorne.w {{(r[0-9])|(lr)}}, {{(r[0-9])|(lr)}}, [[REGISTER]]
|
||||
; CHECK-NOT: eor
|
||||
; CHECK: and
|
||||
%data_addr.013 = phi i8 [ %data, %bb.nph ], [ %8, %bb ] ; <i8> [#uses=2]
|
||||
%crc_addr.112 = phi i16 [ %crc, %bb.nph ], [ %crc_addr.2, %bb ] ; <i16> [#uses=3]
|
||||
%i.011 = phi i8 [ 0, %bb.nph ], [ %7, %bb ] ; <i8> [#uses=1]
|
||||
|
|
Loading…
Reference in New Issue