Index: llvm/lib/Target/ARM/ARMInstrMVE.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrMVE.td +++ llvm/lib/Target/ARM/ARMInstrMVE.td @@ -4973,6 +4973,7 @@ let mayLoad = load; let mayStore = !eq(load,0); + let hasSideEffects = 0; } // A parameter class used to encapsulate all the ways the writeback @@ -5146,6 +5147,7 @@ let mayLoad = dir.load; let mayStore = !eq(dir.load,0); + let hasSideEffects = 0; let validForTailPredication = 1; } Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll =================================================================== --- llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll +++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/mve-float-loops.ll @@ -1357,9 +1357,9 @@ ; CHECK-NEXT: dls lr, lr ; CHECK-NEXT: .LBB8_4: @ %vector.body ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: vldrh.u32 q0, [r5], #8 ; CHECK-NEXT: ldr.w r9, [r4] ; CHECK-NEXT: ldr.w r8, [r4, #4] -; CHECK-NEXT: vldrh.u32 q0, [r5], #8 ; CHECK-NEXT: adds r4, #8 ; CHECK-NEXT: vmov r7, s0 ; CHECK-NEXT: vmov.16 q1[0], r7 Index: llvm/unittests/Target/ARM/MachineInstrTest.cpp =================================================================== --- llvm/unittests/Target/ARM/MachineInstrTest.cpp +++ llvm/unittests/Target/ARM/MachineInstrTest.cpp @@ -525,3 +525,89 @@ } } } + +TEST(MachineInstr, HasSideEffects) { + using namespace ARM; + unsigned Opcodes[] = { + // MVE Loads/Stores + MVE_VLDRBS16, MVE_VLDRBS16_post, MVE_VLDRBS16_pre, + MVE_VLDRBS16_rq, MVE_VLDRBS32, MVE_VLDRBS32_post, + MVE_VLDRBS32_pre, MVE_VLDRBS32_rq, MVE_VLDRBU16, + MVE_VLDRBU16_post, MVE_VLDRBU16_pre, MVE_VLDRBU16_rq, + MVE_VLDRBU32, MVE_VLDRBU32_post, MVE_VLDRBU32_pre, + MVE_VLDRBU32_rq, MVE_VLDRBU8, MVE_VLDRBU8_post, + MVE_VLDRBU8_pre, MVE_VLDRBU8_rq, MVE_VLDRDU64_qi, + MVE_VLDRDU64_qi_pre, MVE_VLDRDU64_rq, MVE_VLDRDU64_rq_u, + MVE_VLDRHS32, MVE_VLDRHS32_post, MVE_VLDRHS32_pre, + MVE_VLDRHS32_rq, MVE_VLDRHS32_rq_u, MVE_VLDRHU16, + MVE_VLDRHU16_post, MVE_VLDRHU16_pre, MVE_VLDRHU16_rq, + MVE_VLDRHU16_rq_u, MVE_VLDRHU32, MVE_VLDRHU32_post, + MVE_VLDRHU32_pre, MVE_VLDRHU32_rq, MVE_VLDRHU32_rq_u, + MVE_VLDRWU32, MVE_VLDRWU32_post, MVE_VLDRWU32_pre, + MVE_VLDRWU32_qi, MVE_VLDRWU32_qi_pre, MVE_VLDRWU32_rq, + MVE_VLDRWU32_rq_u, MVE_VLD20_16, MVE_VLD20_16_wb, + MVE_VLD20_32, MVE_VLD20_32_wb, MVE_VLD20_8, + MVE_VLD20_8_wb, MVE_VLD21_16, MVE_VLD21_16_wb, + MVE_VLD21_32, MVE_VLD21_32_wb, MVE_VLD21_8, + MVE_VLD21_8_wb, MVE_VLD40_16, MVE_VLD40_16_wb, + MVE_VLD40_32, MVE_VLD40_32_wb, MVE_VLD40_8, + MVE_VLD40_8_wb, MVE_VLD41_16, MVE_VLD41_16_wb, + MVE_VLD41_32, MVE_VLD41_32_wb, MVE_VLD41_8, + MVE_VLD41_8_wb, MVE_VLD42_16, MVE_VLD42_16_wb, + MVE_VLD42_32, MVE_VLD42_32_wb, MVE_VLD42_8, + MVE_VLD42_8_wb, MVE_VLD43_16, MVE_VLD43_16_wb, + MVE_VLD43_32, MVE_VLD43_32_wb, MVE_VLD43_8, + MVE_VLD43_8_wb, MVE_VSTRB16, MVE_VSTRB16_post, + MVE_VSTRB16_pre, MVE_VSTRB16_rq, MVE_VSTRB32, + MVE_VSTRB32_post, MVE_VSTRB32_pre, MVE_VSTRB32_rq, + MVE_VSTRB8_rq, MVE_VSTRBU8, MVE_VSTRBU8_post, + MVE_VSTRBU8_pre, MVE_VSTRD64_qi, MVE_VSTRD64_qi_pre, + MVE_VSTRD64_rq, MVE_VSTRD64_rq_u, MVE_VSTRH16_rq, + MVE_VSTRH16_rq_u, MVE_VSTRH32, MVE_VSTRH32_post, + MVE_VSTRH32_pre, MVE_VSTRH32_rq, MVE_VSTRH32_rq_u, + MVE_VSTRHU16, MVE_VSTRHU16_post, MVE_VSTRHU16_pre, + MVE_VSTRW32_qi, MVE_VSTRW32_qi_pre, MVE_VSTRW32_rq, + MVE_VSTRW32_rq_u, MVE_VSTRWU32, MVE_VSTRWU32_post, + MVE_VSTRWU32_pre, MVE_VST20_16, MVE_VST20_16_wb, + MVE_VST20_32, MVE_VST20_32_wb, MVE_VST20_8, + MVE_VST20_8_wb, MVE_VST21_16, MVE_VST21_16_wb, + MVE_VST21_32, MVE_VST21_32_wb, MVE_VST21_8, + MVE_VST21_8_wb, MVE_VST40_16, MVE_VST40_16_wb, + MVE_VST40_32, MVE_VST40_32_wb, MVE_VST40_8, + MVE_VST40_8_wb, MVE_VST41_16, MVE_VST41_16_wb, + MVE_VST41_32, MVE_VST41_32_wb, MVE_VST41_8, + MVE_VST41_8_wb, MVE_VST42_16, MVE_VST42_16_wb, + MVE_VST42_32, MVE_VST42_32_wb, MVE_VST42_8, + MVE_VST42_8_wb, MVE_VST43_16, MVE_VST43_16_wb, + MVE_VST43_32, MVE_VST43_32_wb, MVE_VST43_8, + MVE_VST43_8_wb, + }; + + LLVMInitializeARMTargetInfo(); + LLVMInitializeARMTarget(); + LLVMInitializeARMTargetMC(); + + auto TT(Triple::normalize("thumbv8.1m.main-arm-none-eabi")); + std::string Error; + const Target *T = TargetRegistry::lookupTarget(TT, Error); + if (!T) { + dbgs() << Error; + return; + } + + TargetOptions Options; + auto TM = std::unique_ptr( + static_cast(T->createTargetMachine( + TT, "generic", "", Options, None, None, CodeGenOpt::Default))); + ARMSubtarget ST(TM->getTargetTriple(), TM->getTargetCPU(), + TM->getTargetFeatureString(), + *static_cast(TM.get()), false); + const ARMBaseInstrInfo *TII = ST.getInstrInfo(); + auto MII = TM->getMCInstrInfo(); + + for (unsigned Op : Opcodes) { + const MCInstrDesc &Desc = TII->get(Op); + ASSERT_FALSE(Desc.hasUnmodeledSideEffects()) + << MII->getName(Op) << " has unexpected side effects"; + } +}