optimization whith call of Intrinsics

Dear LLVMer ;

i'm trying to use LLVM for a specific target, using different memory banks.
I have written the frontend to generate a valid IR and want to use the existing passes (as defined in tool opt) to optimize the code.

The target has specific instructions, so following advices given in documentation, I created an intrinsic function, with attribute [IntrReadArgMem].

My test case is very simple : I repeat twice a set of instructions and would like that the optimizer delete the second one;
the set is
{ INSTR 1 : store of data in bank 1;
    INSTR 2 : call of intrinsic (read only)
    INSTR 3 : store of data in bank 2; }

When calling the intrinsic function, the optimizer doesn't work well.
(If I delete INSTR2 and INSTR3, optimization is good)
If I use only one memory bank, the problem is the same. It seems that the call of intrinsics is not well supported by existing optimization passes.
Does anybody have an idea about this problem ? ( just below, the IR generated by LLVM after optimization)


; ModuleID = 'TheModule'
@MemSys = global i16 0 ; <i16*> [#uses=2]
@MemSysSigA = global i16 3 addrspace(2) ; <i16 addrspace(2)*> [#uses=2]
@reg_ai_beg = global i16 405 addrspace(1) ; <i16 addrspace(1)*> [#uses=2]

define void @OFUNC(i16* %N0, i16* %N1) nounwind {
    store i16 1, i16 addrspace(1)* @reg_ai_beg
    %outLLVMInt = tail call i16 @llvm.octo.su.opa.rd(i16* @MemSys) ; <i16> [#uses=1]
    store i16 %outLLVMInt, i16 addrspace(2)* @MemSysSigA
    store i16 1, i16 addrspace(1)* @reg_ai_beg
    %outLLVMInt5 = tail call i16 @llvm.octo.su.opa.rd(i16* @MemSys) ; <i16> [#uses=1]
    store i16 %outLLVMInt5, i16 addrspace(2)* @MemSysSigA
    ret void

declare i16 @llvm.octo.su.opa.rd(i16*) nounwind readonly

Dead store elimination is that pass that could do the optimizations in
question. The second store to @reg_ai_beg should be eliminated; I'm
not really surprised that it doesn't implement this particular case,
though. For the stores to @MemSysSigA, LLVM doesn't know that
llvm.octo.su.opa.rd doesn't read @MemSysSigA, so neither store can be

You should be able to solve both these problems by writing a special
alias analysis pass that knows about the behavior of
llvm.octo.su.opa.rd. See http://llvm.org/docs/AliasAnalysis.html for


Thanks Eli.
I will try your solution, but then, what is the difference between [IntrReadArgMem] and
[IntrReadMem] when specifying an intrinsic ? It seems that both options specify that a function is 'readonly'
(maybe the difference is not well supported for then moment ?)


That's precisely the issue.