From c60a59cad378f484d17ab4d56d58076caedbd4fd Mon Sep 17 00:00:00 2001 From: Christian Pirker Date: Thu, 8 May 2014 14:06:24 +0000 Subject: [PATCH] ARM big endian function argument passing git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208316 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 41 ++++-- test/CodeGen/ARM/atomic-64bit.ll | 131 +++++++++++++------- test/CodeGen/ARM/atomic-ops-v8.ll | 108 ++++++++++------ test/CodeGen/ARM/dagcombine-concatvector.ll | 9 +- test/CodeGen/ARM/func-argpassing-endian.ll | 124 ++++++++++++++++++ test/CodeGen/ARM/longMAC.ll | 21 ++-- test/CodeGen/ARM/long_shift.ll | 58 ++++++--- test/CodeGen/ARM/sub.ll | 21 ++-- test/CodeGen/ARM/vcombine.ll | 39 ++++-- 9 files changed, 412 insertions(+), 140 deletions(-) create mode 100644 test/CodeGen/ARM/func-argpassing-endian.ll diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index a8f0d8cc0f5..8f410b702c5 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1293,6 +1293,8 @@ ARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, InFlag); Chain = Hi.getValue(1); InFlag = Hi.getValue(2); + if (!Subtarget->isLittle()) + std::swap (Lo, Hi); Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi); if (VA.getLocVT() == MVT::v2f64) { @@ -1308,6 +1310,8 @@ ARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InFlag); Chain = Hi.getValue(1); InFlag = Hi.getValue(2); + if (!Subtarget->isLittle()) + std::swap (Lo, Hi); Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi); Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val, DAG.getConstant(1, MVT::i32)); @@ -1358,16 +1362,17 @@ void ARMTargetLowering::PassF64ArgInRegs(SDLoc dl, SelectionDAG &DAG, SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32), Arg); - RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd)); + unsigned id = Subtarget->isLittle() ? 0 : 1; + RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd.getValue(id))); if (NextVA.isRegLoc()) - RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1))); + RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), fmrrd.getValue(1-id))); else { assert(NextVA.isMemLoc()); if (!StackPtr.getNode()) StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); - MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1), + MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1-id), dl, DAG, NextVA, Flags)); } @@ -2082,6 +2087,7 @@ ARMTargetLowering::LowerReturn(SDValue Chain, SDValue Flag; SmallVector RetOps; RetOps.push_back(Chain); // Operand #0 = Chain (updated below) + bool isLittleEndian = Subtarget->isLittle(); // Copy the result values into the output registers. for (unsigned i = 0, realRVLocIdx = 0; @@ -2108,12 +2114,15 @@ ARMTargetLowering::LowerReturn(SDValue Chain, SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32), Half); - Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), HalfGPRs, Flag); + Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), + HalfGPRs.getValue(isLittleEndian ? 0 : 1), + Flag); Flag = Chain.getValue(1); RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); VA = RVLocs[++i]; // skip ahead to next loc Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - HalfGPRs.getValue(1), Flag); + HalfGPRs.getValue(isLittleEndian ? 1 : 0), + Flag); Flag = Chain.getValue(1); RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); VA = RVLocs[++i]; // skip ahead to next loc @@ -2126,11 +2135,14 @@ ARMTargetLowering::LowerReturn(SDValue Chain, // available. SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl, DAG.getVTList(MVT::i32, MVT::i32), Arg); - Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd, Flag); + Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), + fmrrd.getValue(isLittleEndian ? 0 : 1), + Flag); Flag = Chain.getValue(1); RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); VA = RVLocs[++i]; // skip ahead to next loc - Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd.getValue(1), + Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), + fmrrd.getValue(isLittleEndian ? 1 : 0), Flag); } else Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Arg, Flag); @@ -2661,7 +2673,8 @@ ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA, Reg = MF.addLiveIn(NextVA.getLocReg(), RC); ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32); } - + if (!Subtarget->isLittle()) + std::swap (ArgValue, ArgValue2); return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2); } @@ -8314,16 +8327,18 @@ static SDValue PerformSTORECombine(SDNode *N, if (StVal.getNode()->getOpcode() == ARMISD::VMOVDRR && StVal.getNode()->hasOneUse()) { SelectionDAG &DAG = DCI.DAG; + bool isBigEndian = DAG.getTargetLoweringInfo().isBigEndian(); SDLoc DL(St); SDValue BasePtr = St->getBasePtr(); SDValue NewST1 = DAG.getStore(St->getChain(), DL, - StVal.getNode()->getOperand(0), BasePtr, - St->getPointerInfo(), St->isVolatile(), + StVal.getNode()->getOperand(isBigEndian ? 1 : 0 ), + BasePtr, St->getPointerInfo(), St->isVolatile(), St->isNonTemporal(), St->getAlignment()); SDValue OffsetPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, DAG.getConstant(4, MVT::i32)); - return DAG.getStore(NewST1.getValue(0), DL, StVal.getNode()->getOperand(1), + return DAG.getStore(NewST1.getValue(0), DL, + StVal.getNode()->getOperand(isBigEndian ? 0 : 1), OffsetPtr, St->getPointerInfo(), St->isVolatile(), St->isNonTemporal(), std::min(4U, St->getAlignment() / 2)); @@ -10539,6 +10554,8 @@ Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr, Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo"); Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi"); + if (!Subtarget->isLittle()) + std::swap (Lo, Hi); Lo = Builder.CreateZExt(Lo, ValTy, "lo64"); Hi = Builder.CreateZExt(Hi, ValTy, "hi64"); return Builder.CreateOr( @@ -10572,6 +10589,8 @@ Value *ARMTargetLowering::emitStoreConditional(IRBuilder<> &Builder, Value *Val, Value *Lo = Builder.CreateTrunc(Val, Int32Ty, "lo"); Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 32), Int32Ty, "hi"); + if (!Subtarget->isLittle()) + std::swap (Lo, Hi); Addr = Builder.CreateBitCast(Addr, Type::getInt8PtrTy(M->getContext())); return Builder.CreateCall3(Strex, Lo, Hi, Addr); } diff --git a/test/CodeGen/ARM/atomic-64bit.ll b/test/CodeGen/ARM/atomic-64bit.ll index a881d5fd715..9913f30712b 100644 --- a/test/CodeGen/ARM/atomic-64bit.ll +++ b/test/CodeGen/ARM/atomic-64bit.ll @@ -1,12 +1,16 @@ -; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s -; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-THUMB +; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE +; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE +; RUN: llc < %s -mtriple=armebv7 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE +; RUN: llc < %s -mtriple=thumbebv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE define i64 @test1(i64* %ptr, i64 %val) { ; CHECK-LABEL: test1: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK: adds [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK: adc [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE: adds [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE: adc [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: adds [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: adc [[REG3:(r[0-9]?[02468])]], [[REG1]] ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne @@ -15,8 +19,10 @@ define i64 @test1(i64* %ptr, i64 %val) { ; CHECK-THUMB-LABEL: test1: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: adds.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB: adc.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE: adds.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE: adc.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: adds.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: adc.w [[REG3:[a-z0-9]+]], [[REG1]] ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp ; CHECK-THUMB: bne @@ -30,8 +36,10 @@ define i64 @test2(i64* %ptr, i64 %val) { ; CHECK-LABEL: test2: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK: subs [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE: subs [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: subs [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE: sbc [[REG3:(r[0-9]?[02468])]], [[REG1]] ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne @@ -40,8 +48,10 @@ define i64 @test2(i64* %ptr, i64 %val) { ; CHECK-THUMB-LABEL: test2: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: subs.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB: sbc.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE: subs.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE: sbc.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: subs.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE: sbc.w [[REG3:[a-z0-9]+]], [[REG1]] ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp ; CHECK-THUMB: bne @@ -55,8 +65,10 @@ define i64 @test3(i64* %ptr, i64 %val) { ; CHECK-LABEL: test3: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]] ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne @@ -65,8 +77,10 @@ define i64 @test3(i64* %ptr, i64 %val) { ; CHECK-THUMB-LABEL: test3: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]] ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp ; CHECK-THUMB: bne @@ -80,8 +94,10 @@ define i64 @test4(i64* %ptr, i64 %val) { ; CHECK-LABEL: test4: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]] ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne @@ -90,8 +106,10 @@ define i64 @test4(i64* %ptr, i64 %val) { ; CHECK-THUMB-LABEL: test4: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]] ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp ; CHECK-THUMB: bne @@ -105,8 +123,10 @@ define i64 @test5(i64* %ptr, i64 %val) { ; CHECK-LABEL: test5: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]] -; CHECK-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-LE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]] +; CHECK-LE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]] +; CHECK-BE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]] ; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK: cmp ; CHECK: bne @@ -115,8 +135,10 @@ define i64 @test5(i64* %ptr, i64 %val) { ; CHECK-THUMB-LABEL: test5: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]] -; CHECK-THUMB-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-LE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-LE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]] +; CHECK-THUMB-BE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]] ; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]] ; CHECK-THUMB: cmp ; CHECK-THUMB: bne @@ -151,8 +173,10 @@ define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) { ; CHECK-LABEL: test7: ; CHECK: dmb {{ish$}} ; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]] -; CHECK-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG1]], r1 -; CHECK-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2 +; CHECK-LE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG1]], r1 +; CHECK-LE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2 +; CHECK-BE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG2]], r2 +; CHECK-BE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG1]], r1 ; CHECK: orrs {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]] ; CHECK: bne ; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}} @@ -163,8 +187,10 @@ define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) { ; CHECK-THUMB-LABEL: test7: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2 -; CHECK-THUMB-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3 +; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2 +; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3 +; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG1]] +; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG2]] ; CHECK-THUMB: orrs [[MISMATCH_HI]], [[MISMATCH_LO]] ; CHECK-THUMB: bne ; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}} @@ -220,9 +246,11 @@ define i64 @test10(i64* %ptr, i64 %val) { ; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 ; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 -; CHECK: cmp [[REG1]], r1 +; CHECK-LE: cmp [[REG1]], r1 +; CHECK-BE: cmp [[REG2]], r2 ; CHECK: movwls [[CARRY_LO]], #1 -; CHECK: cmp [[REG2]], r2 +; CHECK-LE: cmp [[REG2]], r2 +; CHECK-BE: cmp [[REG1]], r1 ; CHECK: movwle [[CARRY_HI]], #1 ; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK: cmp [[CARRY_HI]], #0 @@ -237,11 +265,13 @@ define i64 @test10(i64* %ptr, i64 %val) { ; CHECK-THUMB-LABEL: test10: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] -; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 -; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 -; CHECK-THUMB: cmp [[REG1]], r2 +; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+|lr]], #0 +; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+|lr]], #0 +; CHECK-THUMB-LE: cmp [[REG1]], r2 +; CHECK-THUMB-BE: cmp [[REG2]], r3 ; CHECK-THUMB: movls.w [[CARRY_LO]], #1 -; CHECK-THUMB: cmp [[REG2]], r3 +; CHECK-THUMB-LE: cmp [[REG2]], r3 +; CHECK-THUMB-BE: cmp [[REG1]], r2 ; CHECK-THUMB: movle [[CARRY_HI]], #1 ; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 @@ -265,9 +295,11 @@ define i64 @test11(i64* %ptr, i64 %val) { ; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 ; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 -; CHECK: cmp [[REG1]], r1 +; CHECK-LE: cmp [[REG1]], r1 +; CHECK-BE: cmp [[REG2]], r2 ; CHECK: movwls [[CARRY_LO]], #1 -; CHECK: cmp [[REG2]], r2 +; CHECK-LE: cmp [[REG2]], r2 +; CHECK-BE: cmp [[REG1]], r1 ; CHECK: movwls [[CARRY_HI]], #1 ; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK: cmp [[CARRY_HI]], #0 @@ -279,15 +311,16 @@ define i64 @test11(i64* %ptr, i64 %val) { ; CHECK: bne ; CHECK: dmb {{ish$}} - ; CHECK-THUMB-LABEL: test11: ; CHECK-THUMB: dmb {{ish$}} ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] ; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 -; CHECK-THUMB: cmp [[REG1]], r2 +; CHECK-THUMB-LE: cmp [[REG1]], r2 +; CHECK-THUMB-BE: cmp [[REG2]], r3 ; CHECK-THUMB: movls.w [[CARRY_LO]], #1 -; CHECK-THUMB: cmp [[REG2]], r3 +; CHECK-THUMB-LE: cmp [[REG2]], r3 +; CHECK-THUMB-BE: cmp [[REG1]], r2 ; CHECK-THUMB: movls [[CARRY_HI]], #1 ; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 @@ -311,9 +344,11 @@ define i64 @test12(i64* %ptr, i64 %val) { ; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 ; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 -; CHECK: cmp [[REG1]], r1 +; CHECK-LE: cmp [[REG1]], r1 +; CHECK-BE: cmp [[REG2]], r2 ; CHECK: movwhi [[CARRY_LO]], #1 -; CHECK: cmp [[REG2]], r2 +; CHECK-LE: cmp [[REG2]], r2 +; CHECK-BE: cmp [[REG1]], r1 ; CHECK: movwgt [[CARRY_HI]], #1 ; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK: cmp [[CARRY_HI]], #0 @@ -330,9 +365,11 @@ define i64 @test12(i64* %ptr, i64 %val) { ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] ; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 -; CHECK-THUMB: cmp [[REG1]], r2 +; CHECK-THUMB-LE: cmp [[REG1]], r2 +; CHECK-THUMB-BE: cmp [[REG2]], r3 ; CHECK-THUMB: movhi.w [[CARRY_LO]], #1 -; CHECK-THUMB: cmp [[REG2]], r3 +; CHECK-THUMB-LE: cmp [[REG2]], r3 +; CHECK-THUMB-BE: cmp [[REG1]], r2 ; CHECK-THUMB: movgt [[CARRY_HI]], #1 ; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 @@ -356,9 +393,11 @@ define i64 @test13(i64* %ptr, i64 %val) { ; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0 ; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2 -; CHECK: cmp [[REG1]], r1 +; CHECK-LE: cmp [[REG1]], r1 +; CHECK-BE: cmp [[REG2]], r2 ; CHECK: movwhi [[CARRY_LO]], #1 -; CHECK: cmp [[REG2]], r2 +; CHECK-LE: cmp [[REG2]], r2 +; CHECK-BE: cmp [[REG1]], r1 ; CHECK: movwhi [[CARRY_HI]], #1 ; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK: cmp [[CARRY_HI]], #0 @@ -375,9 +414,11 @@ define i64 @test13(i64* %ptr, i64 %val) { ; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]] ; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0 ; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0 -; CHECK-THUMB: cmp [[REG1]], r2 +; CHECK-THUMB-LE: cmp [[REG1]], r2 +; CHECK-THUMB-BE: cmp [[REG2]], r3 ; CHECK-THUMB: movhi.w [[CARRY_LO]], #1 -; CHECK-THUMB: cmp [[REG2]], r3 +; CHECK-THUMB-LE: cmp [[REG2]], r3 +; CHECK-THUMB-BE: cmp [[REG1]], r2 ; CHECK-THUMB: movhi [[CARRY_HI]], #1 ; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]] ; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3 diff --git a/test/CodeGen/ARM/atomic-ops-v8.ll b/test/CodeGen/ARM/atomic-ops-v8.ll index 7922e222030..a39565e515c 100644 --- a/test/CodeGen/ARM/atomic-ops-v8.ll +++ b/test/CodeGen/ARM/atomic-ops-v8.ll @@ -1,5 +1,7 @@ -; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM -; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-THUMB +; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-LE +; RUN: llc -mtriple=armebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-BE +; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE +; RUN: llc -mtriple=thumbebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE @var8 = global i8 0 @var16 = global i16 0 @@ -87,8 +89,10 @@ define void @test_atomic_load_add_i64(i64 %offset) nounwind { ; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]] ; r0, r1 below is a reasonable guess but could change: it certainly comes into the ; function there. -; CHECK-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 -; CHECK-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 +; CHECK-LE-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: adds{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-NEXT: adc{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 ; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]] ; CHECK-NEXT: cmp [[STATUS]], #0 ; CHECK-NEXT: bne .LBB{{[0-9]+}}_1 @@ -181,8 +185,10 @@ define void @test_atomic_load_sub_i64(i64 %offset) nounwind { ; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]] ; r0, r1 below is a reasonable guess but could change: it certainly comes into the ; function there. -; CHECK-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 -; CHECK-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-LE-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 +; CHECK-LE-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1 +; CHECK-BE-NEXT: subs{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-NEXT: sbc{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 ; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]] ; CHECK-NEXT: cmp [[STATUS]], #0 ; CHECK-NEXT: bne .LBB{{[0-9]+}}_1 @@ -275,8 +281,10 @@ define void @test_atomic_load_and_i64(i64 %offset) nounwind { ; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]] ; r0, r1 below is a reasonable guess but could change: it certainly comes into the ; function there. -; CHECK-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-LE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 +; CHECK-LE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 ; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]] ; CHECK-NEXT: cmp [[STATUS]], #0 ; CHECK-NEXT: bne .LBB{{[0-9]+}}_1 @@ -369,8 +377,10 @@ define void @test_atomic_load_or_i64(i64 %offset) nounwind { ; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]] ; r0, r1 below is a reasonable guess but could change: it certainly comes into the ; function there. -; CHECK-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 +; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 ; CHECK: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]] ; CHECK-NEXT: cmp [[STATUS]], #0 ; CHECK-NEXT: bne .LBB{{[0-9]+}}_1 @@ -463,8 +473,10 @@ define void @test_atomic_load_xor_i64(i64 %offset) nounwind { ; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]] ; r0, r1 below is a reasonable guess but could change: it certainly comes into the ; function there. -; CHECK-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0 -; CHECK-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 +; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1 +; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0 ; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]] ; CHECK-NEXT: cmp [[STATUS]], #0 ; CHECK-NEXT: bne .LBB{{[0-9]+}}_1 @@ -657,10 +669,14 @@ define void @test_atomic_load_min_i64(i64 %offset) nounwind { ; function there. ; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0 ; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0 -; CHECK-ARM: cmp [[OLD1]], r0 -; CHECK-ARM: movwls [[LOCARRY]], #1 -; CHECK-ARM: cmp [[OLD2]], r1 -; CHECK-ARM: movwle [[HICARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD1]], r0 +; CHECK-ARM-LE: movwls [[LOCARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD2]], r1 +; CHECK-ARM-LE: movwle [[HICARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD2]], r1 +; CHECK-ARM-BE: movwls [[LOCARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD1]], r0 +; CHECK-ARM-BE: movwle [[HICARRY]], #1 ; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]] ; CHECK-ARM: cmp [[HICARRY]], #0 ; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1 @@ -771,10 +787,14 @@ define void @test_atomic_load_max_i64(i64 %offset) nounwind { ; function there. ; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0 ; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0 -; CHECK-ARM: cmp [[OLD1]], r0 -; CHECK-ARM: movwhi [[LOCARRY]], #1 -; CHECK-ARM: cmp [[OLD2]], r1 -; CHECK-ARM: movwgt [[HICARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD1]], r0 +; CHECK-ARM-LE: movwhi [[LOCARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD2]], r1 +; CHECK-ARM-LE: movwgt [[HICARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD2]], r1 +; CHECK-ARM-BE: movwhi [[LOCARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD1]], r0 +; CHECK-ARM-BE: movwgt [[HICARRY]], #1 ; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]] ; CHECK-ARM: cmp [[HICARRY]], #0 ; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1 @@ -885,10 +905,14 @@ define void @test_atomic_load_umin_i64(i64 %offset) nounwind { ; function there. ; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0 ; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0 -; CHECK-ARM: cmp [[OLD1]], r0 -; CHECK-ARM: movwls [[LOCARRY]], #1 -; CHECK-ARM: cmp [[OLD2]], r1 -; CHECK-ARM: movwls [[HICARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD1]], r0 +; CHECK-ARM-LE: movwls [[LOCARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD2]], r1 +; CHECK-ARM-LE: movwls [[HICARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD2]], r1 +; CHECK-ARM-BE: movwls [[LOCARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD1]], r0 +; CHECK-ARM-BE: movwls [[HICARRY]], #1 ; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]] ; CHECK-ARM: cmp [[HICARRY]], #0 ; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1 @@ -999,10 +1023,14 @@ define void @test_atomic_load_umax_i64(i64 %offset) nounwind { ; function there. ; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0 ; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0 -; CHECK-ARM: cmp [[OLD1]], r0 -; CHECK-ARM: movwhi [[LOCARRY]], #1 -; CHECK-ARM: cmp [[OLD2]], r1 -; CHECK-ARM: movwhi [[HICARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD1]], r0 +; CHECK-ARM-LE: movwhi [[LOCARRY]], #1 +; CHECK-ARM-LE: cmp [[OLD2]], r1 +; CHECK-ARM-LE: movwhi [[HICARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD2]], r1 +; CHECK-ARM-BE: movwhi [[LOCARRY]], #1 +; CHECK-ARM-BE: cmp [[OLD1]], r0 +; CHECK-ARM-BE: movwhi [[HICARRY]], #1 ; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]] ; CHECK-ARM: cmp [[HICARRY]], #0 ; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1 @@ -1112,9 +1140,12 @@ define void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind { ; CHECK: ldrexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]] ; r0, r1 below is a reasonable guess but could change: it certainly comes into the ; function there. -; CHECK-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0 -; CHECK-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1 -; CHECK: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]] +; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0 +; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1 +; CHECK-LE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]] +; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1 +; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0 +; CHECK-BE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_HI]], [[MISMATCH_LO]] ; CHECK-NEXT: bne .LBB{{[0-9]+}}_3 ; CHECK-NEXT: BB#2: ; As above, r2, r3 is a reasonable guess. @@ -1151,7 +1182,8 @@ define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind { %val = load atomic i8* %addr monotonic, align 1 ; CHECK-NOT: dmb ; CHECK-NOT: mcr -; CHECK: ldrb r0, [r0, r2] +; CHECK-LE: ldrb r0, [r0, r2] +; CHECK-BE: ldrb r0, [r1, r3] ; CHECK-NOT: dmb ; CHECK-NOT: mcr @@ -1218,7 +1250,8 @@ define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind %val = load atomic i32* %addr monotonic, align 4 ; CHECK-NOT: dmb ; CHECK-NOT: mcr -; CHECK: ldr r0, [r0, r2] +; CHECK-LE: ldr r0, [r0, r2] +; CHECK-BE: ldr r0, [r1, r3] ; CHECK-NOT: dmb ; CHECK-NOT: mcr @@ -1259,8 +1292,10 @@ define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) %addr = inttoptr i64 %addr_int to i8* store atomic i8 %val, i8* %addr monotonic, align 1 -; CHECK: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp] -; CHECK: strb [[VAL]], [r0, r2] +; CHECK-LE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp] +; CHECK-LE: strb [[VAL]], [r0, r2] +; CHECK-BE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp, #3] +; CHECK-BE: strb [[VAL]], [r1, r3] ret void } @@ -1328,7 +1363,8 @@ define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %va ; CHECK: ldr [[VAL:r[0-9]+]], [sp] ; CHECK-NOT: dmb ; CHECK-NOT: mcr -; CHECK: str [[VAL]], [r0, r2] +; CHECK-LE: str [[VAL]], [r0, r2] +; CHECK-BE: str [[VAL]], [r1, r3] ; CHECK-NOT: dmb ; CHECK-NOT: mcr diff --git a/test/CodeGen/ARM/dagcombine-concatvector.ll b/test/CodeGen/ARM/dagcombine-concatvector.ll index 2927ea2f3ca..6cf4fbb6c2e 100644 --- a/test/CodeGen/ARM/dagcombine-concatvector.ll +++ b/test/CodeGen/ARM/dagcombine-concatvector.ll @@ -1,10 +1,13 @@ -; RUN: llc < %s -mtriple=thumbv7s-apple-ios3.0.0 -mcpu=generic | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7s-apple-ios3.0.0 -mcpu=generic | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc < %s -mtriple=thumbeb -mattr=v7,neon | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE ; PR15525 ; CHECK-LABEL: test1: ; CHECK: ldr.w [[REG:r[0-9]+]], [sp] -; CHECK-NEXT: vmov {{d[0-9]+}}, r1, r2 -; CHECK-NEXT: vmov {{d[0-9]+}}, r3, [[REG]] +; CHECK-LE-NEXT: vmov {{d[0-9]+}}, r1, r2 +; CHECK-LE-NEXT: vmov {{d[0-9]+}}, r3, [[REG]] +; CHECK-BE-NEXT: vmov {{d[0-9]+}}, r2, r1 +; CHECK-BE-NEXT: vmov {{d[0-9]+}}, [[REG]], r3 ; CHECK-NEXT: vst1.8 {{{d[0-9]+}}, {{d[0-9]+}}}, [r0] ; CHECK-NEXT: bx lr define void @test1(i8* %arg, [4 x i64] %vec.coerce) { diff --git a/test/CodeGen/ARM/func-argpassing-endian.ll b/test/CodeGen/ARM/func-argpassing-endian.ll new file mode 100644 index 00000000000..7c957525849 --- /dev/null +++ b/test/CodeGen/ARM/func-argpassing-endian.ll @@ -0,0 +1,124 @@ +; RUN: llc -verify-machineinstrs < %s -march=arm -mattr=v7,neon | FileCheck --check-prefix=CHECK --check-prefix=CHECK-LE %s +; RUN: llc -verify-machineinstrs < %s -march=armeb -mattr=v7,neon | FileCheck --check-prefix=CHECK --check-prefix=CHECK-BE %s + +@var32 = global i32 0 +@vardouble = global double 0.0 + +define void @arg_longint( i64 %val ) { +; CHECK-LABEL: arg_longint: +; CHECK-LE: str r0, [r1] +; CHECK-BE: str r1, [r0] + %tmp = trunc i64 %val to i32 + store i32 %tmp, i32* @var32 + ret void +} + +define void @arg_double( double %val ) { +; CHECK-LABEL: arg_double: +; CHECK: strd r0, r1, [r2] + store double %val, double* @vardouble + ret void +} + +define void @arg_v4i32(<4 x i32> %vec ) { +; CHECK-LABEL: arg_v4i32: +; CHECK-LE: vmov d17, r2, r3 +; CHECK-LE: vmov d16, r0, r1 +; CHECK-BE: vmov d17, r3, r2 +; CHECK-BE: vmov d16, r1, r0 +; CHECK: vst1.32 {d16[0]}, [r0:32] + %tmp = extractelement <4 x i32> %vec, i32 0 + store i32 %tmp, i32* @var32 + ret void +} + +define void @arg_v2f64(<2 x double> %vec ) { +; CHECK-LABEL: arg_v2f64: +; CHECK: strd r0, r1, [r2] + %tmp = extractelement <2 x double> %vec, i32 0 + store double %tmp, double* @vardouble + ret void +} + +define i64 @return_longint() { +; CHECK-LABEL: return_longint: +; CHECK-LE: mov r0, #42 +; CHECK-LE: mov r1, #0 +; CHECK-BE: mov r0, #0 +; CHECK-BE: mov r1, #42 + ret i64 42 +} + +define double @return_double() { +; CHECK-LABEL: return_double: +; CHECK-LE: vmov r0, r1, d16 +; CHECK-BE: vmov r1, r0, d16 + ret double 1.0 +} + +define <4 x i32> @return_v4i32() { +; CHECK-LABEL: return_v4i32: +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 + ret < 4 x i32> < i32 42, i32 43, i32 44, i32 45 > +} + +define <2 x double> @return_v2f64() { +; CHECK-LABEL: return_v2f64: +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 + ret <2 x double> < double 3.14, double 6.28 > +} + +define void @caller_arg_longint() { +; CHECK-LABEL: caller_arg_longint: +; CHECK-LE: mov r0, #42 +; CHECK-LE: mov r1, #0 +; CHECK-BE: mov r0, #0 +; CHECK-BE: mov r1, #42 + call void @arg_longint( i64 42 ) + ret void +} + +define void @caller_arg_double() { +; CHECK-LABEL: caller_arg_double: +; CHECK-LE: vmov r0, r1, d16 +; CHECK-BE: vmov r1, r0, d16 + call void @arg_double( double 1.0 ) + ret void +} + +define void @caller_return_longint() { +; CHECK-LABEL: caller_return_longint: +; CHECK-LE: str r0, [r1] +; CHECK-BE: str r1, [r0] + %val = call i64 @return_longint() + %tmp = trunc i64 %val to i32 + store i32 %tmp, i32* @var32 + ret void +} + +define void @caller_return_double() { +; CHECK-LABEL: caller_return_double: +; CHECK-LE: vmov d17, r0, r1 +; CHECK-BE: vmov d17, r1, r0 + %val = call double @return_double( ) + %tmp = fadd double %val, 3.14 + store double %tmp, double* @vardouble + ret void +} + +define void @caller_return_v2f64() { +; CHECK-LABEL: caller_return_v2f64: +; CHECK: strd r0, r1, [r2] + %val = call <2 x double> @return_v2f64( ) + %tmp = extractelement <2 x double> %val, i32 0 + store double %tmp, double* @vardouble + ret void +} + + diff --git a/test/CodeGen/ARM/longMAC.ll b/test/CodeGen/ARM/longMAC.ll index 5636a12c203..fed6ec02f32 100644 --- a/test/CodeGen/ARM/longMAC.ll +++ b/test/CodeGen/ARM/longMAC.ll @@ -1,5 +1,7 @@ -; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefix=CHECK-V7 +; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-LE +; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefix=CHECK-V7-LE +; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE +; RUN: llc -mtriple=armebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-BE ; Check generated signed and unsigned multiply accumulate long. define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) { @@ -53,13 +55,18 @@ define i64 @MACLongTest4(i32 %a, i32 %b, i32 %c) { ; function, both after the umlal. With it, *some* move has to happen ; before the umlal. define i64 @MACLongTest5(i64 %c, i32 %a, i32 %b) { -; CHECK-V7-LABEL: MACLongTest5: -; CHECK-V7-LABEL: umlal r0, r1, r0, r0 +; CHECK-V7-LE-LABEL: MACLongTest5: +; CHECK-V7-LE-LABEL: umlal r0, r1, r0, r0 +; CHECK-V7-BE-LABEL: MACLongTest5: +; CHECK-V7-BE-LABEL: umlal r1, r0, r1, r1 ; CHECK-LABEL: MACLongTest5: -; CHECK: mov [[RDLO:r[0-9]+]], r0 -; CHECK: umlal [[RDLO]], r1, r0, r0 -; CHECK: mov r0, [[RDLO]] +; CHECK-LE: mov [[RDLO:r[0-9]+]], r0 +; CHECK-LE: umlal [[RDLO]], r1, r0, r0 +; CHECK-LE: mov r0, [[RDLO]] +; CHECK-BE: mov [[RDLO:r[0-9]+]], r1 +; CHECK-BE: umlal [[RDLO]], r0, r1, r1 +; CHECK-BE: mov r1, [[RDLO]] %conv.trunc = trunc i64 %c to i32 %conv = zext i32 %conv.trunc to i64 diff --git a/test/CodeGen/ARM/long_shift.ll b/test/CodeGen/ARM/long_shift.ll index 48b0ba7ecaa..3ec5fa41aa6 100644 --- a/test/CodeGen/ARM/long_shift.ll +++ b/test/CodeGen/ARM/long_shift.ll @@ -1,11 +1,16 @@ -; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s +; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE define i64 @f0(i64 %A, i64 %B) { ; CHECK-LABEL: f0: -; CHECK: lsrs r3, r3, #1 -; CHECK-NEXT: rrx r2, r2 -; CHECK-NEXT: subs r0, r0, r2 -; CHECK-NEXT: sbc r1, r1, r3 +; CHECK-LE: lsrs r3, r3, #1 +; CHECK-LE-NEXT: rrx r2, r2 +; CHECK-LE-NEXT: subs r0, r0, r2 +; CHECK-LE-NEXT: sbc r1, r1, r3 +; CHECK-BE: lsrs r2, r2, #1 +; CHECK-BE-NEXT: rrx r3, r3 +; CHECK-BE-NEXT: subs r1, r1, r3 +; CHECK-BE-NEXT: sbc r0, r0, r2 %tmp = bitcast i64 %A to i64 %tmp2 = lshr i64 %B, 1 %tmp3 = sub i64 %tmp, %tmp2 @@ -14,7 +19,8 @@ define i64 @f0(i64 %A, i64 %B) { define i32 @f1(i64 %x, i64 %y) { ; CHECK-LABEL: f1: -; CHECK: lsl{{.*}}r2 +; CHECK-LE: lsl{{.*}}r2 +; CHECK-BE: lsl{{.*}}r3 %a = shl i64 %x, %y %b = trunc i64 %a to i32 ret i32 %b @@ -22,12 +28,20 @@ define i32 @f1(i64 %x, i64 %y) { define i32 @f2(i64 %x, i64 %y) { ; CHECK-LABEL: f2: -; CHECK: lsr{{.*}}r2 -; CHECK-NEXT: rsb r3, r2, #32 -; CHECK-NEXT: sub r2, r2, #32 -; CHECK-NEXT: orr r0, r0, r1, lsl r3 -; CHECK-NEXT: cmp r2, #0 -; CHECK-NEXT: asrge r0, r1, r2 +; CHECK-LE: lsr{{.*}}r2 +; CHECK-LE-NEXT: rsb r3, r2, #32 +; CHECK-LE-NEXT: sub r2, r2, #32 +; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3 +; CHECK-LE-NEXT: cmp r2, #0 +; CHECK-LE-NEXT: asrge r0, r1, r2 + +; CHECK-BE: lsr{{.*}}r3 +; CHECK-BE-NEXT: rsb r2, r3, #32 +; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2 +; CHECK-BE-NEXT: sub r2, r3, #32 +; CHECK-BE-NEXT: cmp r2, #0 +; CHECK-BE-NEXT: asrge r1, r0, r2 + %a = ashr i64 %x, %y %b = trunc i64 %a to i32 ret i32 %b @@ -35,12 +49,20 @@ define i32 @f2(i64 %x, i64 %y) { define i32 @f3(i64 %x, i64 %y) { ; CHECK-LABEL: f3: -; CHECK: lsr{{.*}}r2 -; CHECK-NEXT: rsb r3, r2, #32 -; CHECK-NEXT: sub r2, r2, #32 -; CHECK-NEXT: orr r0, r0, r1, lsl r3 -; CHECK-NEXT: cmp r2, #0 -; CHECK-NEXT: lsrge r0, r1, r2 +; CHECK-LE: lsr{{.*}}r2 +; CHECK-LE-NEXT: rsb r3, r2, #32 +; CHECK-LE-NEXT: sub r2, r2, #32 +; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3 +; CHECK-LE-NEXT: cmp r2, #0 +; CHECK-LE-NEXT: lsrge r0, r1, r2 + +; CHECK-BE: lsr{{.*}}r3 +; CHECK-BE-NEXT: rsb r2, r3, #32 +; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2 +; CHECK-BE-NEXT: sub r2, r3, #32 +; CHECK-BE-NEXT: cmp r2, #0 +; CHECK-BE-NEXT: lsrge r1, r0, r2 + %a = lshr i64 %x, %y %b = trunc i64 %a to i32 ret i32 %b diff --git a/test/CodeGen/ARM/sub.ll b/test/CodeGen/ARM/sub.ll index 67bde2a4e0a..9ac314dd608 100644 --- a/test/CodeGen/ARM/sub.ll +++ b/test/CodeGen/ARM/sub.ll @@ -1,10 +1,13 @@ -; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s +; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc -mtriple=armeb-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE ; 171 = 0x000000ab define i64 @f1(i64 %a) { ; CHECK: f1 -; CHECK: subs r0, r0, #171 -; CHECK: sbc r1, r1, #0 +; CHECK-LE: subs r0, r0, #171 +; CHECK-LE: sbc r1, r1, #0 +; CHECK-BE: subs r1, r1, #171 +; CHECK-BE: sbc r0, r0, #0 %tmp = sub i64 %a, 171 ret i64 %tmp } @@ -12,8 +15,10 @@ define i64 @f1(i64 %a) { ; 66846720 = 0x03fc0000 define i64 @f2(i64 %a) { ; CHECK: f2 -; CHECK: subs r0, r0, #66846720 -; CHECK: sbc r1, r1, #0 +; CHECK-LE: subs r0, r0, #66846720 +; CHECK-LE: sbc r1, r1, #0 +; CHECK-BE: subs r1, r1, #66846720 +; CHECK-BE: sbc r0, r0, #0 %tmp = sub i64 %a, 66846720 ret i64 %tmp } @@ -21,8 +26,10 @@ define i64 @f2(i64 %a) { ; 734439407618 = 0x000000ab00000002 define i64 @f3(i64 %a) { ; CHECK: f3 -; CHECK: subs r0, r0, #2 -; CHECK: sbc r1, r1, #171 +; CHECK-LE: subs r0, r0, #2 +; CHECK-LE: sbc r1, r1, #171 +; CHECK-BE: subs r1, r1, #2 +; CHECK-BE: sbc r0, r0, #171 %tmp = sub i64 %a, 734439407618 ret i64 %tmp } diff --git a/test/CodeGen/ARM/vcombine.ll b/test/CodeGen/ARM/vcombine.ll index d611267fc7f..11d2f3f9c66 100644 --- a/test/CodeGen/ARM/vcombine.ll +++ b/test/CodeGen/ARM/vcombine.ll @@ -1,9 +1,12 @@ -; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+neon %s -o - | FileCheck %s +; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+neon %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc -mtriple=armeb-eabi -float-abi=soft -mattr=+neon %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE define <16 x i8> @vcombine8(<8 x i8>* %A, <8 x i8>* %B) nounwind { ; CHECK: vcombine8 -; CHECK: vmov r0, r1, d16 -; CHECK: vmov r2, r3, d17 +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 %tmp1 = load <8 x i8>* %A %tmp2 = load <8 x i8>* %B %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <16 x i32> @@ -12,8 +15,10 @@ define <16 x i8> @vcombine8(<8 x i8>* %A, <8 x i8>* %B) nounwind { define <8 x i16> @vcombine16(<4 x i16>* %A, <4 x i16>* %B) nounwind { ; CHECK: vcombine16 -; CHECK: vmov r0, r1, d16 -; CHECK: vmov r2, r3, d17 +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 %tmp1 = load <4 x i16>* %A %tmp2 = load <4 x i16>* %B %tmp3 = shufflevector <4 x i16> %tmp1, <4 x i16> %tmp2, <8 x i32> @@ -22,8 +27,10 @@ define <8 x i16> @vcombine16(<4 x i16>* %A, <4 x i16>* %B) nounwind { define <4 x i32> @vcombine32(<2 x i32>* %A, <2 x i32>* %B) nounwind { ; CHECK: vcombine32 -; CHECK: vmov r0, r1, d16 -; CHECK: vmov r2, r3, d17 +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 %tmp1 = load <2 x i32>* %A %tmp2 = load <2 x i32>* %B %tmp3 = shufflevector <2 x i32> %tmp1, <2 x i32> %tmp2, <4 x i32> @@ -32,8 +39,10 @@ define <4 x i32> @vcombine32(<2 x i32>* %A, <2 x i32>* %B) nounwind { define <4 x float> @vcombinefloat(<2 x float>* %A, <2 x float>* %B) nounwind { ; CHECK: vcombinefloat -; CHECK: vmov r0, r1, d16 -; CHECK: vmov r2, r3, d17 +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 %tmp1 = load <2 x float>* %A %tmp2 = load <2 x float>* %B %tmp3 = shufflevector <2 x float> %tmp1, <2 x float> %tmp2, <4 x i32> @@ -42,8 +51,10 @@ define <4 x float> @vcombinefloat(<2 x float>* %A, <2 x float>* %B) nounwind { define <2 x i64> @vcombine64(<1 x i64>* %A, <1 x i64>* %B) nounwind { ; CHECK: vcombine64 -; CHECK: vmov r0, r1, d16 -; CHECK: vmov r2, r3, d17 +; CHECK-LE: vmov r0, r1, d16 +; CHECK-LE: vmov r2, r3, d17 +; CHECK-BE: vmov r1, r0, d16 +; CHECK-BE: vmov r3, r2, d17 %tmp1 = load <1 x i64>* %A %tmp2 = load <1 x i64>* %B %tmp3 = shufflevector <1 x i64> %tmp1, <1 x i64> %tmp2, <2 x i32> @@ -56,7 +67,8 @@ define <2 x i64> @vcombine64(<1 x i64>* %A, <1 x i64>* %B) nounwind { define <4 x i16> @vget_low16(<8 x i16>* %A) nounwind { ; CHECK: vget_low16 ; CHECK-NOT: vst -; CHECK: vmov r0, r1, d16 +; CHECK-LE: vmov r0, r1, d16 +; CHECK-BE: vmov r1, r0, d16 %tmp1 = load <8 x i16>* %A %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <4 x i32> ret <4 x i16> %tmp2 @@ -65,7 +77,8 @@ define <4 x i16> @vget_low16(<8 x i16>* %A) nounwind { define <8 x i8> @vget_high8(<16 x i8>* %A) nounwind { ; CHECK: vget_high8 ; CHECK-NOT: vst -; CHECK: vmov r0, r1, d17 +; CHECK-LE: vmov r0, r1, d17 +; CHECK-BE: vmov r1, r0, d17 %tmp1 = load <16 x i8>* %A %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <8 x i32> ret <8 x i8> %tmp2 -- 2.34.1