From 416941d50fec5ebdc4ae3b113a0db1320c3b2a87 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 4 Nov 2010 05:19:35 +0000 Subject: [PATCH] Fix @llvm.prefetch isel. Selecting between pld / pldw using the first immediate rw. There is currently no intrinsic that matches to pli. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118237 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 21 +++++++++++---------- lib/Target/ARM/ARMInstrInfo.td | 24 +++++++++++------------- lib/Target/ARM/ARMInstrThumb2.td | 30 +++++++++++++++--------------- test/CodeGen/ARM/prefetch.ll | 29 +++++++++++++---------------- 4 files changed, 50 insertions(+), 54 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 0cc6f2298bf..5a3520e3a2b 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -597,7 +597,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, Expand); setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i64, Expand); - setOperationAction(ISD::PREFETCH, MVT::Other, Custom); + setOperationAction(ISD::PREFETCH, MVT::Other, Custom); // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes. if (!Subtarget->hasV6Ops()) { @@ -2068,20 +2068,21 @@ static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG, return Op.getOperand(0); DebugLoc dl = Op.getDebugLoc(); - unsigned Flavor = cast(Op.getOperand(3))->getZExtValue(); - if (Flavor != 3) { - if (!Subtarget->hasV7Ops()) - return Op.getOperand(0); - else if (Flavor == 2 && !Subtarget->hasMPExtension()) - return Op.getOperand(0); - } + unsigned isRead = ~cast(Op.getOperand(2))->getZExtValue() & 1; + if (!isRead && + (!Subtarget->hasV7Ops() || !Subtarget->hasMPExtension())) + // ARMv7 with MP extension has PLDW. + 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) { diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index c98d45bf43d..4c61ffb55ca 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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 data_read, string opc> { +multiclass APreLoad 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 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", diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index b105bc7eed6..6569664414f 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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 instr_write, string opc> { +multiclass T2Ipl 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 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 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. diff --git a/test/CodeGen/ARM/prefetch.ll b/test/CodeGen/ARM/prefetch.ll index 1e4ff30af78..895b27b749d 100644 --- a/test/CodeGen/ARM/prefetch.ll +++ b/test/CodeGen/ARM/prefetch.ll @@ -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] -- 2.11.0