[PATCH] D78929: [AIX][XCOFF]emit extern linkage for the llvm intrinsic symbol

Xiangling Liao via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 21 17:53:23 PDT 2020


Xiangling_L added a comment.

Can you also please update the testcase `aix-user-defined-memcpy.ll` to include:
`CHECK-NOT: .extern .memcpy`



================
Comment at: llvm/lib/Target/PowerPC/PPCISelLowering.cpp:5283
+    if (Subtarget.isAIXABI()) {
+      // If there exists a user-declared function whose name is the same as the
+      // ExternalSymbol's, then we pick up the user-declared version.
----------------
jasonliu wrote:
> sfertile wrote:
> > I'm not too familiar with when we get ExternalSymbolSDNodes or what the semantic should be if we have an ExternalSymbolSDNode and a IR declaration for the same function, but it seems odd to treat the situation differently based on XCOFF vs ELF. @Xiangling_L Was `aix-user-defined-memcpy.ll` motivated by real code? If so I'd like to investigate it a bit more.
> It seems for real C code. If there is a user-provided memset/memcpy, clang would transform the call to that user-provided memset/memcpy instead of generating llvm.memset/memcpy intrinsic.
Just as a record. As we discussed offline, a real C code is like:

```
int memcpy ( void * destination, int num ) { return 3; }
typedef struct cpy_array {
  int array[20];
} cpy;
int main() {
  cpy A = {1,2,3,4,5,6,7,8,9,10, 11, 12, 13, 14, 15,16};
  cpy B = A;
  return B.array[0];
}
```

And Clang FE will generate the following IR for AIX:
```
; Function Attrs: noinline nounwind optnone
define i32 @memcpy(i8* %destination, i32 %num) #0 {
entry:
  %destination.addr = alloca i8*, align 4
  %num.addr = alloca i32, align 4
  store i8* %destination, i8** %destination.addr, align 4
  store i32 %num, i32* %num.addr, align 4
  ret i32 3
}
; Function Attrs: noinline nounwind optnone
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %A = alloca %struct.cpy_array, align 4
  %B = alloca %struct.cpy_array, align 4
  store i32 0, i32* %retval, align 4
  %0 = bitcast %struct.cpy_array* %A to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast (%struct.cpy_array* @__const.main.A to i8*), i32 80, i1 false)
  %1 = bitcast %struct.cpy_array* %B to i8*
  %2 = bitcast %struct.cpy_array* %A to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 4 %2, i32 80, i1 false)
  %array = getelementptr inbounds %struct.cpy_array, %struct.cpy_array* %B, i32 0, i32 0
  %arrayidx = getelementptr inbounds [20 x i32], [20 x i32]* %array, i32 0, i32 0
  %3 = load i32, i32* %arrayidx, align 4
  ret i32 %3
}
```



================
Comment at: llvm/test/CodeGen/PowerPC/aix-cc-byval-mem.ll:91
 ; 32BIT-DAG:      $r5 = COPY %2
-; 32BIT-NEXT:     BL_NOP <mcsymbol .memcpy>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r2, implicit-def $r1, implicit-def $r3
+; 32BIT-NEXT:     BL_NOP &.memcpy, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r2, implicit-def $r1, implicit-def $r3
 ; 32BIT-NEXT:     ADJCALLSTACKUP 56, 0, implicit-def dead $r1, implicit $r1
----------------
Though unrelated to this patch, I am wondering if we can replace `&` to something more meaningful like `extsym` etc. like what we have for MCSymbol as `mcsymbol`?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78929/new/

https://reviews.llvm.org/D78929





More information about the llvm-commits mailing list