From 2b68e64b54ecf593bbb65d5490100f533cfefc8f Mon Sep 17 00:00:00 2001 From: Colin McEwan Date: Tue, 4 Jul 2023 21:35:40 +0100 Subject: [PATCH 1/2] Add test for volatile store merged to swm --- .../Mips/nanomips/test-volatile-swm.ll | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll diff --git a/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll b/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll new file mode 100644 index 00000000000000..a581296d26076a --- /dev/null +++ b/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll @@ -0,0 +1,24 @@ +; RUN: llc -march=nanomips < %s | FileCheck %s +target datalayout = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128" +target triple = "nanomips" + +%struct.S = type { i32, i32 } + +declare dso_local inreg { i32, i32 } @GetStruct(...) local_unnamed_addr + +define dso_local void @test(%struct.S* %p, i32 signext %i) local_unnamed_addr { +entry: +; CHECK-NOT: swm +; CHECK: sw +; CHECK: sw + %call = tail call inreg { i32, i32 } bitcast ({ i32, i32 } (...)* @GetStruct to { i32, i32 } ()*)() + %0 = extractvalue { i32, i32 } %call, 0 + %1 = extractvalue { i32, i32 } %call, 1 + %B1 = getelementptr inbounds %struct.S, %struct.S* %p, i32 0, i32 1 + store volatile i32 %1, i32* %B1, align 4 + %A26 = bitcast %struct.S* %p to i32* + store volatile i32 %0, i32* %A26, align 4 + ret void +} +; CHECK: astemunhtobeix + From 1e75b90d176ed9225a315ddd72b72838cd2b3c9e Mon Sep 17 00:00:00 2001 From: Colin McEwan Date: Tue, 4 Jul 2023 21:42:25 +0100 Subject: [PATCH 2/2] Avoid swm/lwm of volatile accesses. Merging volatile accesses into lwm/swm can change the order of accesses and may have other undesirable effects. --- llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp | 7 +++++++ llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp index 56c303c8484186..3e3498d025793f 100644 --- a/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp +++ b/llvm/lib/Target/Mips/NanoMipsLoadStoreOptimizer.cpp @@ -429,6 +429,13 @@ unsigned NMLoadStoreOpt::getRegNo(unsigned Reg) { bool NMLoadStoreOpt::isValidLoadStore(MachineInstr &MI, bool IsLoad) { unsigned Opcode = MI.getOpcode(); + + // Make sure the instruction doesn't have any atomic, volatile or + // otherwise strictly ordered accesses. + for (auto &MMO : MI.memoperands()) + if (MMO->isAtomic() || !MMO->isUnordered()) + return false; + if (IsLoad) { // TODO: Handle unaligned loads and stores. if (Opcode == Mips::LW_NM || Opcode == Mips::LWs9_NM) { diff --git a/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll b/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll index a581296d26076a..e058e0d42d9c3a 100644 --- a/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll +++ b/llvm/test/CodeGen/Mips/nanomips/test-volatile-swm.ll @@ -4,7 +4,7 @@ target triple = "nanomips" %struct.S = type { i32, i32 } -declare dso_local inreg { i32, i32 } @GetStruct(...) local_unnamed_addr +declare dso_local inreg { i32, i32 } @GetStruct(...) local_unnamed_addr define dso_local void @test(%struct.S* %p, i32 signext %i) local_unnamed_addr { entry: @@ -20,5 +20,4 @@ entry: store volatile i32 %0, i32* %A26, align 4 ret void } -; CHECK: astemunhtobeix