mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 21:00:29 +00:00
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
b04daa462f
commit
eef813bb47
@ -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);
|
||||
|
31
test/CodeGen/ARM/shift-combine.ll
Normal file
31
test/CodeGen/ARM/shift-combine.ll
Normal file
@ -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
Block a user