Skip to content

Commit

Permalink
[DPWBS-1401] Truncate the len argument to memory intrinsics to 32-bits.
Browse files Browse the repository at this point in the history
LLVM and clang use hard-coded types when creating calls to memory intrinsics in cirtain situations.
In some cases, the type is hard-coded to i64, which is passed in an extended register on TriCore.
When lowering the intrinsic to the corresponding C library function, this results in an ABI mismatch which
breaks at runtime.

For now, we truncate the len argument to 32-bits to work around this problem.
  • Loading branch information
konstantinschwarz committed Jun 18, 2020
1 parent 109ce0a commit 3c6aa40
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 2 deletions.
34 changes: 32 additions & 2 deletions llvm/lib/Target/TriCore/TriCoreLegalizerInfo.cpp
Expand Up @@ -625,12 +625,42 @@ bool TriCoreLegalizerInfo::legalizeIntrinsic(
switch (MI.getIntrinsicID()) {
case Intrinsic::memcpy:
case Intrinsic::memset:
case Intrinsic::memmove:
if (createMemLibcall(MIRBuilder, *MIRBuilder.getMRI(), MI) ==
case Intrinsic::memmove: {

// Unfortunately LLVM (still) allows to create memory intrinsics with
// types that do not match the prototype of the corresponding C library
// functions. Therefore, we trunc the size of the len argument to 32-bits.
// If the len type is < 32-bit, it will be extended to 32-bits by the call
// lowering code.
// FIXME: this hack should be removed once LLVM restricts the use of the
// memory intrinsics
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
MachineOperand &SizeOp = MI.getOperand(3);
Register SizeReg = SizeOp.getReg();
LLT SizeTy = MRI.getType(SizeReg);
if (SizeTy.getSizeInBits() > 32) {

// If the len argument is a constant, simply create a new s32 constant
auto VRegAndVal = getConstantVRegValWithLookThrough(SizeReg, MRI);
if (VRegAndVal) {
Register NewConstant =
MRI.createGenericVirtualRegister(LLT::scalar(32));
MIRBuilder.buildConstant(NewConstant, VRegAndVal->Value);
SizeOp.setReg(NewConstant);
} else {
// Otherwise, we need to truncate the source register to 32-bits
Register TruncReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
MIRBuilder.buildTrunc(TruncReg, SizeReg);
SizeOp.setReg(TruncReg);
}
}

if (createMemLibcall(MIRBuilder, MRI, MI) ==
LegalizerHelper::UnableToLegalize)
return false;
MI.eraseFromParent();
return true;
}
case Intrinsic::vacopy: {
MachinePointerInfo MPO;

Expand Down
173 changes: 173 additions & 0 deletions llvm/test/CodeGen/TriCore/GlobalIsel/legalize-memcpy-et-al.mir
Expand Up @@ -26,6 +26,63 @@ body: |
RET implicit $a11
...

---
name: test_memcpy_s64_imm
tracksRegLiveness: true
body: |
bb.1:
liveins: $a4, $a5
; CHECK-LABEL: name: test_memcpy_s64_imm
; CHECK: liveins: $a4, $a5
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $a4
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $a5
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $a10, implicit $a10
; CHECK: $a4 = COPY [[COPY]](p0)
; CHECK: $a5 = COPY [[COPY1]](p0)
; CHECK: $d4 = COPY [[C]](s32)
; CHECK: CALL &memcpy, csr_tricore_uppercontext, implicit-def $a11, implicit $psw, implicit $a4, implicit $a5, implicit $d4
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $a10, implicit $a10
; CHECK: RET implicit $a11
%0:_(p0) = COPY $a4
%1:_(p0) = COPY $a5
%2:_(s64) = G_CONSTANT i64 4
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), %0(p0), %1(p0), %2(s64), 0
RET implicit $a11
...

---
name: test_memcpy_s64
tracksRegLiveness: true
body: |
bb.1:
liveins: $a4, $a5, $e4
; CHECK-LABEL: name: test_memcpy_s64
; CHECK: liveins: $a4, $a5, $e4
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $a4
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $a5
; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $e4
; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64)
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $a10, implicit $a10
; CHECK: $a4 = COPY [[COPY]](p0)
; CHECK: $a5 = COPY [[COPY1]](p0)
; CHECK: $d4 = COPY [[TRUNC]](s32)
; CHECK: CALL &memcpy, csr_tricore_uppercontext, implicit-def $a11, implicit $psw, implicit $a4, implicit $a5, implicit $d4
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $a10, implicit $a10
; CHECK: RET implicit $a11
%0:_(p0) = COPY $a4
%1:_(p0) = COPY $a5
%2:_(s64) = COPY $e4
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), %0(p0), %1(p0), %2(s64), 0
RET implicit $a11
...


---
name: test_memmove
tracksRegLiveness: true
Expand All @@ -52,6 +109,64 @@ body: |
RET implicit $a11
...

---
name: test_memmove_s64_imm
tracksRegLiveness: true
body: |
bb.1:
liveins: $a4, $a5
; CHECK-LABEL: name: test_memmove_s64_imm
; CHECK: liveins: $a4, $a5
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $a4
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $a5
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $a10, implicit $a10
; CHECK: $a4 = COPY [[COPY]](p0)
; CHECK: $a5 = COPY [[COPY1]](p0)
; CHECK: $d4 = COPY [[C]](s32)
; CHECK: CALL &memmove, csr_tricore_uppercontext, implicit-def $a11, implicit $psw, implicit $a4, implicit $a5, implicit $d4
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $a10, implicit $a10
; CHECK: RET implicit $a11
%0:_(p0) = COPY $a4
%1:_(p0) = COPY $a5
%2:_(s64) = G_CONSTANT i64 4
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memmove), %0(p0), %1(p0), %2(s64), 0
RET implicit $a11
...

---
name: test_memmove_s64
tracksRegLiveness: true
body: |
bb.1:
liveins: $a4, $a5, $e4
; CHECK-LABEL: name: test_memmove_s64
; CHECK: liveins: $a4, $a5, $e4
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $a4
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $a5
; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $e4
; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64)
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $a10, implicit $a10
; CHECK: $a4 = COPY [[COPY]](p0)
; CHECK: $a5 = COPY [[COPY1]](p0)
; CHECK: $d4 = COPY [[TRUNC]](s32)
; CHECK: CALL &memmove, csr_tricore_uppercontext, implicit-def $a11, implicit $psw, implicit $a4, implicit $a5, implicit $d4
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $a10, implicit $a10
; CHECK: RET implicit $a11
%0:_(p0) = COPY $a4
%1:_(p0) = COPY $a5
%2:_(s64) = COPY $e4
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memmove), %0(p0), %1(p0), %2(s64), 0
RET implicit $a11
...



---
name: test_memset
tracksRegLiveness: true
Expand Down Expand Up @@ -81,3 +196,61 @@ body: |
...

---
name: test_memset_s64_imm
tracksRegLiveness: true
body: |
bb.1:
liveins: $a4, $d4
; CHECK-LABEL: name: test_memset_s64_imm
; CHECK: liveins: $a4, $d4
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $a4
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $d4
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $a10, implicit $a10
; CHECK: $a4 = COPY [[COPY]](p0)
; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
; CHECK: $d4 = COPY [[COPY2]](s32)
; CHECK: $d5 = COPY [[C]](s32)
; CHECK: CALL &memset, csr_tricore_uppercontext, implicit-def $a11, implicit $psw, implicit $a4, implicit $d4, implicit $d5
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $a10, implicit $a10
; CHECK: RET implicit $a11
%0:_(p0) = COPY $a4
%1:_(s32) = COPY $d4
%2:_(s64) = G_CONSTANT i64 4
%3:_(s8) = G_TRUNC %1(s32)
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memset), %0(p0), %3(s8), %2(s64), 0
RET implicit $a11
...

---
name: test_memset_s64
tracksRegLiveness: true
body: |
bb.1:
liveins: $a4, $d4, $e6
; CHECK-LABEL: name: test_memset_s64
; CHECK: liveins: $a4, $d4, $e6
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $a4
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $d4
; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $e6
; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64)
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $a10, implicit $a10
; CHECK: $a4 = COPY [[COPY]](p0)
; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
; CHECK: $d4 = COPY [[COPY3]](s32)
; CHECK: $d5 = COPY [[TRUNC]](s32)
; CHECK: CALL &memset, csr_tricore_uppercontext, implicit-def $a11, implicit $psw, implicit $a4, implicit $d4, implicit $d5
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $a10, implicit $a10
; CHECK: RET implicit $a11
%0:_(p0) = COPY $a4
%1:_(s32) = COPY $d4
%2:_(s64) = COPY $e6
%3:_(s8) = G_TRUNC %1(s32)
G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memset), %0(p0), %3(s8), %2(s64), 0
RET implicit $a11
...

0 comments on commit 3c6aa40

Please sign in to comment.