llvm-project icon indicating copy to clipboard operation
llvm-project copied to clipboard

optimize for builtin functions

Open BaoshanPang opened this issue 3 years ago • 4 comments

Is it possible to teach llvm do optimizations on builtin functions? For such code:

void test_mtspr() {
__builtin_ppc_mtspr(3,5);
__builtin_ppc_mtspr(3,5);
}

With command:

clang -cc1 -internal-isystem ~/mywork/llvm/build/lib/clang/15.0.0/include -nostdsysteminc -triple powerpc-unknown-unknown -S y.c -O2

The generated asm code is like this:

# %bb.0:                                # %entry
    li 3, 5
    mtudscr 3
    mtudscr 3
    blr

Can LLVM remove the second mtudscr?

BaoshanPang avatar Jul 22 '22 19:07 BaoshanPang

Try adding proper properties for the builtin here https://github.com/llvm/llvm-project/blob/6710b21d46987257b9b97105c9128c63eec2fb57/llvm/include/llvm/IR/IntrinsicsPowerPC.td#L1656-L1657

The list of properties is here: https://github.com/llvm/llvm-project/blob/43dc319049516c586f5ece974e618baf40d737a5/llvm/include/llvm/IR/Intrinsics.td#L17-L163

yuanfang-chen avatar Jul 23 '22 03:07 yuanfang-chen

@yuanfang-chen Thanks for the gudie. but it seems beside changing the code in IntrinsicsPowerPC.td, there is more places to change. With this change:

modified   llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1650,7 +1650,7 @@ let TargetPrefix = "ppc" in {
   def int_ppc_mtmsr
       : GCCBuiltin<"__builtin_ppc_mtmsr">, Intrinsic<[], [llvm_i32_ty], []>;
   def int_ppc_mtspr
-      : Intrinsic<[], [llvm_i32_ty, llvm_anyint_ty], [ImmArg<ArgIndex<0>>]>;
+      : Intrinsic<[], [llvm_i32_ty, llvm_anyint_ty], [IntrNoMem, ImmArg<ArgIndex<0>>]>;
   def int_ppc_stfiw : GCCBuiltin<"__builtin_ppc_stfiw">,
                       Intrinsic<[], [llvm_ptr_ty, llvm_double_ty],
                                 [IntrWriteMem]>;

These errors are showing up in building:

Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPC.td:511:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCSchedule.td:131:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstrInfo.td:3256:
/home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1969:1: error: inferred from pattern
def : Pat<(int_ppc_mtspr timm:$SPR, g8rc:$RT),
^
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPC.td:511:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCSchedule.td:131:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstrInfo.td:3258:
/home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstrHTM.td:152:1: error: pattern has side effects, but hasSideEffects isn't set on the instruction
def : Pat<(int_ppc_set_tfiar i64:$V),
^
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPC.td:511:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCSchedule.td:131:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstrInfo.td:3256:
/home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstr64Bit.td:559:1: error: defined here
def MTSPR8 : XFXForm_1<31, 467, (outs), (ins i32imm:$SPR, g8rc:$RT),
^
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPC.td:511:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCSchedule.td:131:
Included from /home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstrInfo.td:3256:
/home/bpang/mywork/llvm_fort/llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1969:1: error: inferred from pattern
def : Pat<(int_ppc_mtspr timm:$SPR, g8rc:$RT),
^
error: Errors in DAG patterns

BaoshanPang avatar Jul 23 '22 04:07 BaoshanPang

Sorry. This is definitely out of my expertise. One more thing I noticed is that the instruction has side effects. https://pages.cs.wisc.edu/~tesch/doc/mtspr.html

If __builtin_ppc_mtspr has side effects but mtudscr does not, then this optimization probably should be done in the PPC backend.

yuanfang-chen avatar Jul 23 '22 05:07 yuanfang-chen

@llvm/issue-subscribers-backend-powerpc

llvmbot avatar Aug 16 '22 19:08 llvmbot

If you want to make build successful here, add line let hasSideEffects = 1 in before def MTSPR8 in PPCInstr64Bit.td. But that is incorrect because IntrNoMem will instruct the optimizer to clear all such instructions if their results are not used.

Besides, mtspr may change many things (see mtspr) and intrinsics tablegen cannot support attributes for certain constant argument. Even when two consequent mtspr can be merged for some SPR ids, we still need to carefully model dependency with it and other neighboring instructions.

ecnelises avatar Sep 01 '22 08:09 ecnelises