Preserving the order of WRITE_REGISTER, READ_REGISTER in IR and ISelDAG


I have a few questions regarding intrinsics llvm.write_register, llvm.read_register and the corresponding selection DAG node types ISD::WRITE_REGISTER, ISD::READ_REGISTER. As background, I'll mention that Clang emits these in response to variables declared as ``register int eax asm("eax");''

(1) Per include/llvm/IR/, the intrinsic llvm.write_register is modeled with a memory side effect, but llvm.read_register is not (i.e, the intrinsic is declared with IntrNoMem). If I understand correctly, this means that the relative ordering of calls to llvm.write_register will be preserved, but that optimizations may freely reorder llvm.read_register. Why is this? It seems like llvm.read_register should be ordered w.r.t. llvm.write_register, or the register-asm syntax is pretty much useless.

(2) Per SelectionDAGBuilder::visitIntrinsicCall, the Chain operand for ISD::WRITE_REGISTER SDNodes is derived from the second operand of the llvm.write_register intrinsic call (i.e., from the value being written to the registger), as follows:

  // excerpt from lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  case Intrinsic::write_register: {
    Value *Reg = I.getArgOperand(0);
    Value *RegValue = I.getArgOperand(1);
    SDValue Chain = getValue(RegValue).getOperand(0);
    SDValue RegName =
    DAG.setRoot(DAG.getNode(ISD::WRITE_REGISTER, sdl, MVT::Other, Chain,
      RegName, getValue(RegValue)));
    return nullptr;

Is this a bug? It seems that the chain should instead be the selection DAG root, as so:

- SDValue Chain = getValue(RegValue).getOperand(0);
+ SDValue Chain = DAG.getRoot();

Thank you,

FYI, I have submitted a bug and a proposed fix: