forked from OSchip/llvm-project
Fix @llvm.prefetch isel. Selecting between pld / pldw using the first immediate rw. There is currently no intrinsic that matches to pli.
llvm-svn: 118237
This commit is contained in:
parent
2683fd6f8c
commit
21acf9fb38
|
@ -2068,20 +2068,21 @@ static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG,
|
|||
return Op.getOperand(0);
|
||||
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
unsigned Flavor = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
|
||||
if (Flavor != 3) {
|
||||
if (!Subtarget->hasV7Ops())
|
||||
unsigned isRead = ~cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() & 1;
|
||||
if (!isRead &&
|
||||
(!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension()))
|
||||
// ARMv7 with MP extension has PLDW.
|
||||
return Op.getOperand(0);
|
||||
else if (Flavor == 2 && !Subtarget->hasMPExtension())
|
||||
return Op.getOperand(0);
|
||||
}
|
||||
|
||||
if (Subtarget->isThumb())
|
||||
// Invert the bits.
|
||||
Flavor = ~Flavor & 0x3;
|
||||
isRead = ~isRead & 1;
|
||||
unsigned isData = Subtarget->isThumb() ? 0 : 1;
|
||||
|
||||
// Currently there is no intrinsic that matches pli.
|
||||
return DAG.getNode(ARMISD::PRELOAD, dl, MVT::Other, Op.getOperand(0),
|
||||
Op.getOperand(1), DAG.getConstant(Flavor, MVT::i32));
|
||||
Op.getOperand(1), DAG.getConstant(isRead, MVT::i32),
|
||||
DAG.getConstant(isData, MVT::i32));
|
||||
}
|
||||
|
||||
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) {
|
||||
|
|
|
@ -62,8 +62,6 @@ def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
|||
|
||||
def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
|
||||
|
||||
def SDT_ARMPRELOAD : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
|
||||
|
||||
def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||
|
||||
def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
|
||||
|
@ -132,7 +130,7 @@ def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER,
|
|||
[SDNPHasChain]>;
|
||||
def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER,
|
||||
[SDNPHasChain]>;
|
||||
def ARMPreload : SDNode<"ARMISD::PRELOAD", SDT_ARMPRELOAD,
|
||||
def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch,
|
||||
[SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
|
||||
|
||||
def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
|
||||
|
@ -994,18 +992,18 @@ def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
|
|||
|
||||
// Preload signals the memory system of possible future data/instruction access.
|
||||
// These are for disassembly only.
|
||||
multiclass APreLoad<bits<2> data_read, string opc> {
|
||||
multiclass APreLoad<bits<1> read, bits<1> data, string opc> {
|
||||
|
||||
def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload,
|
||||
!strconcat(opc, "\t$addr"),
|
||||
[(ARMPreload addrmode_imm12:$addr, (i32 data_read))]> {
|
||||
[(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> {
|
||||
bits<4> Rt;
|
||||
bits<17> addr;
|
||||
let Inst{31-26} = 0b111101;
|
||||
let Inst{25} = 0; // 0 for immediate form
|
||||
let Inst{24} = data_read{1};
|
||||
let Inst{24} = data;
|
||||
let Inst{23} = addr{12}; // U (add = ('U' == 1))
|
||||
let Inst{22} = data_read{0};
|
||||
let Inst{22} = read;
|
||||
let Inst{21-20} = 0b01;
|
||||
let Inst{19-16} = addr{16-13}; // Rn
|
||||
let Inst{15-12} = Rt;
|
||||
|
@ -1014,23 +1012,23 @@ multiclass APreLoad<bits<2> data_read, string opc> {
|
|||
|
||||
def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload,
|
||||
!strconcat(opc, "\t$shift"),
|
||||
[(ARMPreload ldst_so_reg:$shift, (i32 data_read))]> {
|
||||
[(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> {
|
||||
bits<4> Rt;
|
||||
bits<17> shift;
|
||||
let Inst{31-26} = 0b111101;
|
||||
let Inst{25} = 1; // 1 for register form
|
||||
let Inst{24} = data_read{1};
|
||||
let Inst{24} = data;
|
||||
let Inst{23} = shift{12}; // U (add = ('U' == 1))
|
||||
let Inst{22} = data_read{0};
|
||||
let Inst{22} = read;
|
||||
let Inst{21-20} = 0b01;
|
||||
let Inst{19-16} = shift{16-13}; // Rn
|
||||
let Inst{11-0} = shift{11-0};
|
||||
}
|
||||
}
|
||||
|
||||
defm PLD : APreLoad<3, "pld">, Requires<[IsARM]>;
|
||||
defm PLDW : APreLoad<2, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
|
||||
defm PLI : APreLoad<1, "pli">, Requires<[IsARM,HasV7]>;
|
||||
defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>;
|
||||
defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>;
|
||||
defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>;
|
||||
|
||||
def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary,
|
||||
"setend\t$end",
|
||||
|
|
|
@ -1173,28 +1173,28 @@ def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
|
|||
// data/instruction access. These are for disassembly only.
|
||||
// instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0),
|
||||
// (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1).
|
||||
multiclass T2Ipl<bits<2> instr_write, string opc> {
|
||||
multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> {
|
||||
|
||||
def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc,
|
||||
"\t$addr",
|
||||
[(ARMPreload t2addrmode_imm12:$addr, (i32 instr_write))]> {
|
||||
[(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> {
|
||||
let Inst{31-25} = 0b1111100;
|
||||
let Inst{24} = instr_write{1};
|
||||
let Inst{24} = instr;
|
||||
let Inst{23} = 1; // U = 1
|
||||
let Inst{22} = 0;
|
||||
let Inst{21} = instr_write{0};
|
||||
let Inst{21} = write;
|
||||
let Inst{20} = 1;
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
|
||||
def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc,
|
||||
"\t$addr",
|
||||
[(ARMPreload t2addrmode_imm8:$addr, (i32 instr_write))]> {
|
||||
[(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> {
|
||||
let Inst{31-25} = 0b1111100;
|
||||
let Inst{24} = instr_write{1};
|
||||
let Inst{24} = instr;
|
||||
let Inst{23} = 0; // U = 0
|
||||
let Inst{22} = 0;
|
||||
let Inst{21} = instr_write{0};
|
||||
let Inst{21} = write;
|
||||
let Inst{20} = 1;
|
||||
let Inst{15-12} = 0b1111;
|
||||
let Inst{11-8} = 0b1100;
|
||||
|
@ -1202,12 +1202,12 @@ multiclass T2Ipl<bits<2> instr_write, string opc> {
|
|||
|
||||
def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc,
|
||||
"\t$addr",
|
||||
[(ARMPreload t2addrmode_so_reg:$addr, (i32 instr_write))]> {
|
||||
[(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> {
|
||||
let Inst{31-25} = 0b1111100;
|
||||
let Inst{24} = instr_write{1};
|
||||
let Inst{24} = instr;
|
||||
let Inst{23} = 0; // add = TRUE for T1
|
||||
let Inst{22} = 0;
|
||||
let Inst{21} = instr_write{0};
|
||||
let Inst{21} = write;
|
||||
let Inst{20} = 1;
|
||||
let Inst{15-12} = 0b1111;
|
||||
let Inst{11-6} = 0000000;
|
||||
|
@ -1218,19 +1218,19 @@ multiclass T2Ipl<bits<2> instr_write, string opc> {
|
|||
"\t$addr",
|
||||
[]> {
|
||||
let Inst{31-25} = 0b1111100;
|
||||
let Inst{24} = instr_write{1};
|
||||
let Inst{24} = write;
|
||||
let Inst{23} = ?; // add = (U == 1)
|
||||
let Inst{22} = 0;
|
||||
let Inst{21} = instr_write{0};
|
||||
let Inst{21} = instr;
|
||||
let Inst{20} = 1;
|
||||
let Inst{19-16} = 0b1111; // Rn = 0b1111
|
||||
let Inst{15-12} = 0b1111;
|
||||
}
|
||||
}
|
||||
|
||||
defm t2PLD : T2Ipl<0, "pld">, Requires<[IsThumb2]>;
|
||||
defm t2PLDW : T2Ipl<1, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
|
||||
defm t2PLI : T2Ipl<2, "pli">, Requires<[IsThumb2,HasV7]>;
|
||||
defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>;
|
||||
defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>;
|
||||
defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Load / store multiple Instructions.
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
; RUN: llc < %s -march=thumb -mattr=-thumb2 | not grep pld
|
||||
; RUN: llc < %s -march=thumb -mattr=+v7a,+mp | FileCheck %s -check-prefix=THUMB2
|
||||
; RUN: llc < %s -march=arm -mattr=+v7a,+mp | FileCheck %s -check-prefix=ARM
|
||||
; RUN: llc < %s -march=thumb -mattr=+v7a | FileCheck %s -check-prefix=THUMB2
|
||||
; RUN: llc < %s -march=arm -mattr=+v7a,+mp | FileCheck %s -check-prefix=ARM-MP
|
||||
; rdar://8601536
|
||||
|
||||
define void @t1(i8* %ptr) nounwind {
|
||||
entry:
|
||||
; ARM: t1:
|
||||
; ARM: pli [r0]
|
||||
; ARM: pldw [r0]
|
||||
; ARM: pld [r0]
|
||||
; ARM-MP: t1:
|
||||
; ARM-MP: pldw [r0]
|
||||
; ARM-MP: pld [r0]
|
||||
|
||||
; THUMB2: t1:
|
||||
; THUMB2: pli [r0]
|
||||
; THUMB2: pldw [r0]
|
||||
; THUMB2-NOT: pldw [r0]
|
||||
; THUMB2: pld [r0]
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 1 )
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 2 )
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 1, i32 3 )
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 3 )
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t2(i8* %ptr) nounwind {
|
||||
entry:
|
||||
; ARM: t2:
|
||||
; ARM: pld [r0, #1023]
|
||||
; ARM-MP: t2:
|
||||
; ARM-MP: pld [r0, #1023]
|
||||
|
||||
; THUMB2: t2:
|
||||
; THUMB2: pld [r0, #1023]
|
||||
|
@ -34,8 +31,8 @@ entry:
|
|||
|
||||
define void @t3(i32 %base, i32 %offset) nounwind {
|
||||
entry:
|
||||
; ARM: t3:
|
||||
; ARM: pld [r0, r1, lsr #2]
|
||||
; ARM-MP: t3:
|
||||
; ARM-MP: pld [r0, r1, lsr #2]
|
||||
|
||||
; THUMB2: t3:
|
||||
; THUMB2: lsrs r1, r1, #2
|
||||
|
@ -49,8 +46,8 @@ entry:
|
|||
|
||||
define void @t4(i32 %base, i32 %offset) nounwind {
|
||||
entry:
|
||||
; ARM: t4:
|
||||
; ARM: pld [r0, r1, lsl #2]
|
||||
; ARM-MP: t4:
|
||||
; ARM-MP: pld [r0, r1, lsl #2]
|
||||
|
||||
; THUMB2: t4:
|
||||
; THUMB2: pld [r0, r1, lsl #2]
|
||||
|
|
Loading…
Reference in New Issue