The way to access metadata in IR from MachineInstr

I have a question, and I would like you to help me.

I would like to utilize the LLVMIR metadata in backend. But I have no idea about how to access from llvm::MachineInstr to llvm::Instruction’s metadata. Is there any LLVM API to access in that way? Especially, I would like to correspond with llvm::MachineInstr and llvm::Instruction.
It seems that there is some discussions about that, but I don’t know what to do.

Not in general. There are some specific instances where IR instruction metadata is manually attached to specific MIR constructs (e.g. range metadata in the memory operands). There isn’t a general mechanism.

Thanks for you reply.
I’ve understood that there isn’t a general mechanism after hearing your reply. Then if we want to change a general IR instruction to a new assembly instruction dependent on a target architecture using metadata, what stage should we use metadata at? For exaple, we assume that we want to change the store IR instruction to mystore1 or mystore2 assembly instruction and which store asm is ouput depends on IR metadata added to store IR. How do we do to achive it?

Depends why you want to do this. Specifically for stores, you can access the underlying pointer value through the memory operand

1 Like

I’m in the middle of implementing my original backend, about which I cannot describe in detail.
I would like to move analysis data of LLVM IR to my original backend. Because LLVM IR is SSA format and is easy to analyze program code. To move analysis data to backend, I thought it was a good idea to utilize LLVM IR metadata, but I’ve found it difficult to do it.
For example, we assume we find these instructions in LLVM IR.

%8 = load i16, i16* %7, align 2, !tbaa !4
%9 = add i64 %8, 1
store i16 %9, i16* %8, align 2, !tbaa !4

Then I want to unit these instructions and transform to a SLADDi assembly instruction for my original backend.

If I try to implement it in MyBackendISelLowering.cpp by using custom action, I have to anarize Selection DAG. But Selection DAG is more complex than LLVM IR and it is more difficult to analize.

Here is an example. These are the same basic blocks. You can find it more difficult to analize SelectionDAG than IR.

IR

39:                                               ; preds = %39, %.preheader
  %40 = phi i64 [ 0, %.preheader ], [ %68, %39 ]
  %41 = getelementptr inbounds [1000 x i16], [1000 x i16]* %1, i64 0, i64 %40
  %42 = load i16, i16* %41, align 2, !tbaa !4
  %43 = add i16 %42, 1
  store i16 %43, i16* %41, align 2, !tbaa !4
  %44 = getelementptr inbounds [1000 x i16], [1000 x i16]* %2, i64 0, i64 %40
  %45 = load i16, i16* %44, align 2, !tbaa !4
  %46 = add i16 %45, 1
  store i16 %46, i16* %44, align 2, !tbaa !4
  %47 = add nuw nsw i64 %40, 1
  %48 = getelementptr inbounds [1000 x i16], [1000 x i16]* %1, i64 0, i64 %47
  %49 = load i16, i16* %48, align 2, !tbaa !4
  %50 = add i16 %49, 1
  store i16 %50, i16* %48, align 2, !tbaa !4
  %51 = getelementptr inbounds [1000 x i16], [1000 x i16]* %2, i64 0, i64 %47
  %52 = load i16, i16* %51, align 2, !tbaa !4
  %53 = add i16 %52, 1
  store i16 %53, i16* %51, align 2, !tbaa !4
  %54 = add nuw nsw i64 %47, 1
  %55 = getelementptr inbounds [1000 x i16], [1000 x i16]* %1, i64 0, i64 %54
  %56 = load i16, i16* %55, align 2, !tbaa !4
  %57 = add i16 %56, 1
  store i16 %57, i16* %55, align 2, !tbaa !4
  %58 = getelementptr inbounds [1000 x i16], [1000 x i16]* %2, i64 0, i64 %54
  %59 = load i16, i16* %58, align 2, !tbaa !4
  %60 = add i16 %59, 1
  store i16 %60, i16* %58, align 2, !tbaa !4
  %61 = add nuw nsw i64 %54, 1
  %62 = getelementptr inbounds [1000 x i16], [1000 x i16]* %1, i64 0, i64 %61
  %63 = load i16, i16* %62, align 2, !tbaa !4
  %64 = add i16 %63, 1
  store i16 %64, i16* %62, align 2, !tbaa !4
  %65 = getelementptr inbounds [1000 x i16], [1000 x i16]* %2, i64 0, i64 %61
  %66 = load i16, i16* %65, align 2, !tbaa !4
  %67 = add i16 %66, 1
  store i16 %67, i16* %65, align 2, !tbaa !4
  %68 = add nuw nsw i64 %61, 1
  %69 = icmp eq i64 %68, 1000
  br i1 %69, label %27, label %39, !llvm.loop !11

SelectionDAG

Optimized lowered selection DAG: %bb.4 'main:'
SelectionDAG has 59 nodes:
  t0: ch = EntryToken
  t7: i64,ch = CopyFromReg t0, Register:i64 %8
  t8: i64 = add FrameIndex:i64<0>, t7
  t11: i16,ch = load<(load 2 from %ir.33, !tbaa !4)> t0, t8, undef:i64
  t16: i64 = add FrameIndex:i64<1>, t7
    t2: i64,ch = CopyFromReg t0, Register:i64 %7
  t20: i64 = add t2, t7
  t22: i64 = add t20, Constant:i64<-4>
        t18: i16 = add t59, Constant:i16<1>
      t61: ch = store<(store 2 into %ir.37, !tbaa !4)> t59:1, t18, t16, undef:i64
        t13: i16 = add t11, Constant:i16<1>
      t14: ch = store<(store 2 into %ir.33, !tbaa !4)> t11:1, t13, t8, undef:i64
    t63: ch = TokenFactor t61, t14
  t23: i16,ch = load<(load 2 from %ir.scevgep21, !tbaa !4)> t63, t22, undef:i64
    t4: i64,ch = CopyFromReg t0, Register:i64 %6
  t26: i64 = add t4, t7
  t28: i64 = add t26, Constant:i64<-2>
      t24: i16 = add t23, Constant:i16<1>
    t25: ch = store<(store 2 into %ir.scevgep21, !tbaa !4)> t23:1, t24, t22, undef:i64
  t29: i16,ch = load<(load 2 from %ir.scevgep11, !tbaa !4)> t25, t28, undef:i64
  t32: i64 = add t20, Constant:i64<-2>
      t30: i16 = add t29, Constant:i16<1>
    t31: ch = store<(store 2 into %ir.scevgep11, !tbaa !4)> t29:1, t30, t28, undef:i64
  t33: i16,ch = load<(load 2 from %ir.scevgep24, !tbaa !4)> t31, t32, undef:i64
      t34: i16 = add t33, Constant:i16<1>
    t35: ch = store<(store 2 into %ir.scevgep24, !tbaa !4)> t33:1, t34, t32, undef:i64
  t36: i16,ch = load<(load 2 from %ir.uglygep2, !tbaa !4)> t35, t26, undef:i64
      t37: i16 = add t36, Constant:i16<1>
    t38: ch = store<(store 2 into %ir.uglygep2, !tbaa !4)> t36:1, t37, t26, undef:i64
  t39: i16,ch = load<(load 2 from %ir.uglygep1415, !tbaa !4)> t38, t20, undef:i64
  t43: i64 = add t26, Constant:i64<2>
      t40: i16 = add t39, Constant:i16<1>
    t41: ch = store<(store 2 into %ir.uglygep1415, !tbaa !4)> t39:1, t40, t20, undef:i64
  t44: i16,ch = load<(load 2 from %ir.scevgep8, !tbaa !4)> t41, t43, undef:i64
  t48: i64 = add nuw nsw t7, Constant:i64<8>
  t59: i16,ch = load<(load 2 from %ir.37, !tbaa !4)> t0, t16, undef:i64
        t50: ch = CopyToReg t0, Register:i64 %9, t48
          t45: i16 = add t44, Constant:i16<1>
        t46: ch = store<(store 2 into %ir.scevgep8, !tbaa !4)> t44:1, t45, t43, undef:i64
      t55: ch = TokenFactor t50, t46
      t53: i1 = setcc t48, Constant:i64<2000>, seteq:ch
    t56: ch = brcond t55, t53, BasicBlock:ch< 0x5584eea9d1f0>
  t58: ch = br t56, BasicBlock:ch< 0x5584eea9d2c8>

So I want to know the way to utilize IR metadata for my original backend.

TBAA is already tracked in the memory operand for stores

1 Like