<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/70337>70337</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            CCIfPtr appears to always be false in return calling conventions
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          camilstaps
      </td>
    </tr>
</table>

<pre>
    I am trying to implement an X86 calling convention using register pinning. It is similar to the GHC/HiPe conventions, but I also want to pin registers in return values. My idea was to define the new convention and delegate the return convention to it:

```
def CC_X86_64_New : CallingConv<[
  CCIfPtr<CCAssignToReg<[RDI, RSI, RCX, RDX, R8]>>,
  CCIfType<[i64], CCAssignToReg<[R15, RAX, RBX, R10, R11, R12, R13, R14]>>,
]>;

def CC_X86_64 : CallingConv<[
  // ...
 CCIfCC<"CallingConv::New", CCDelegateTo<CC_X86_64_New>>,
  // ...
]>;

def RetCC_X86_64_New : CallingConv<[
 CCDelegateTo<CC_X86_64_New>
]>;

def RetCC_X86_64 : CallingConv<[
  // ...
  CCIfCC<"CallingConv::New", CCDelegateTo<RetCC_X86_64_New>>,
  // ...
]>;
```

As you can see, I would like to assign `ptr` and `i64` to different registers. This seems to work for the argument convention, but not for the return convention. Thus, while I would expect the following function to be a no-op, it actually generates code to move values around:

```llvm
define newcc { ptr, ptr, i64 } @f(ptr %0, ptr %1, i64 %2) {
  %4 = insertvalue { ptr, ptr, i64 } undef, ptr %0, 0
  %5 = insertvalue { ptr, ptr, i64 } %4, ptr %1, 1
 %6 = insertvalue { ptr, ptr, i64 } %5, i64 %2, 2
  ret { ptr, ptr, i64 } %6
}
```

```assembly
        movq    %r15, %rbx
        movq    %rsi, %rax
        movq    %rdi, %r15
        retq
```

It is as if in the return convention, `CCIfPtr` is never true, and instead all pointers are treated as `i64`.

Is this intentional? I notice that very few conventions use `CCIfPtr`, so perhaps it isn't meant to be used?

If this *should* work, I would be happy to provide a branch where you can try this out.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVk1z4jgQ_TXi0hWXkbGBAwdilh0OOzWVzSG3lGy3sXZkySPJePj3Wy0DgSSTnWwVRYPV_frDek8Szsm9Rlyx9J6lm4nofWPsqhStVM6Lzk0KUx1XOxAteHuUeg_egGw7hS1qD0LD0yKDUihFa6XRB9ReGg29owcW99J5tNBJraXeR7DzIB042UolLIH5BuHPLznj2y_yG15BOMZzKHoPOxDKGRiE9hTQSX3BdRD--N5qOAjVo4vgryPICgUMwpF7hbXUGNJoHK5LFLqCChXuhR_XT0BXLtSsZ8maxRsWn7-z-PQJfyusIc-fnxbZczZ7_ooDsGQN-TiR3OgDS3KabnAGyPNd_c1bluR5vg7TfzQPuB-dHjY7avrh79HkT8FsRrNg6YYlf9CH59dwj8cOx3iZzciJ5_Ae-DQNOOsR7n4003g009Hw0SSjmb1NeX5yfz2Smxl83D_jW8a3EEXR6Ql1kOfkxPlN1Jol6684MM7HhjanV_VowvCuJv5mKq-T_LLoB_S__-7-q4TfT_XJEf3PGb1u7tNjut3o4_fawdH0UAoNDpGy7mAwvapAye9IhBk1BVgWd96yLA48Y1lMmzOLAyVlXaMl_bjwOILHhnQBsQ2sHYz9DrWxgZfC7vsgNy_MPGuDNv7i9oa-BNoHGRkaqfBSKf7ssPQhpjZKmYGkqu51eeZ8gSBAmzvTUbD0IErfC6WOsEeNVnh0UJoqtNuaA560B4Q1va5-pRdKHdrLfiBN0jiUJbD5PdCkeH42knbIfANsFteMLzpvgfE0PnnQ7-nFjaec8SWBvLzVlDbYBqR2aH0o7YMkva6wvoIOaeIrsPQTYJT7dZnTExbjafY5qPS2yxz4uSyL_uPQ7DT7-eaDvXx5KJzDtlDH8-KyNYcfLF4yntpRNelX8fO9dSfP6-Ld9eqyPk0v6xb9jw8KGw9J4UDWdMC9u7kDahafz5MsphCNB7TgbR-YScST2nkUFQiloDNSh0NTWARvUXisKMuFnNFNEQ48cZJiQkahWLKFHXFOlnRiCg8HtEeob85VB73D29KoGGegQ9uIzhGhpNOMzz20eDrVC6SwiiXbmxrqsQbG164h7jK-DtpwLTwFQiO67hguB9YcZEX0LazQZQNDgxYvkuXtcQQ0vY8m1SqplslSTHA1zZaLJIn5fDFpVkUsymXG55iWfBnPylKkuEhnNRfVLJsnfCJXPObJNObZdMZnySKqkzhNUz5Pp4uKV0tksxhbIVVEnI-M3U-kcz2u5nGSzCdKFKhcuHNxTpeSsEginm4mdkUxd0W_d2wWK-m8e0Hx0itcnQYLoutQ2KCXQg3i6GgUtVAOr65Fb-9mbtJbtWq87xxJVTgE9tI3fRGVpmV8G4RqNHedNf9g6RnfhiId49vQxL8BAAD__9ZLBHE">