How to differ from read and write operations for general stack objects

The following is the code fragment after "# *** IR Dump Before Prolog/Epilog Insertion & Frame Finalization :".
MOV32mi <fi#2>, 1, %reg0, 0, %reg0, 0
MOV32mr <fi#2>, 1, %reg0, 0, %reg0, %ECX
_
%EAX = MOV32rm <fi#2>, 1, %reg0, 0, %reg0
*_
MOV32mr %reg0, 1, %reg0, ga:one+4, %reg0, %EAX
%EAX = MOV32rm <fi#2>, 1, %reg0, 0, %reg0
ADJCALLSTACKDOWN32 8, %ESP<imp-def,dead>, %EFLAGS<imp-def,dead>, %ESP
%ECX = MOV32rr %ESP
MOV32mr %ECX, 1, %reg0, 4, %reg0, %EAX; mem:ST4[Stack+4]
MOV32mi %ECX, 1, %reg0, 0, %reg0, ga:.str; mem:ST4[Stack]
CALLpcrel32 ga:printf, %EAX, %ECX<imp-def,dead>, %ESP, …
ADJCALLSTACKUP32 8, 0, %ESP<imp-def,dead>, %EFLAGS<imp-def,dead>, %ESP
MOV32mi <fi#1>, 1, %reg0, 0, %reg0, 0
%ECX = MOV32rm <fi#1>, 1, %reg0, 0, %reg0
MOV32mr <fi#0>, 1, %reg0, 0, %reg0, %ECX
MOV32mr <fi#3>, 1, %reg0, 0, %reg0, %EAX; mem:ST4[FixedStack3]

It seems the ways to identify read/write are different for virtual registers, and stack objects.For virtual registers, we could use the MachineOperand::isDef() and MachineOperand::isUse.
For stack objects used for argument-passing (see mem:ST4[Stack] in the example) or return-value (see mem:ST4[FixedStack3]), we could use the MachineMemOperand::IsLoad() and MachineMemOperand::IsStore().
For general stack objects, like the first and second instructions in the example, is there a way for me to identify whether fi#2 is read or written?