diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 98117a24fce..d96c2080ffa 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -74,6 +74,13 @@ Changes to building LLVM Changes to TableGen ------------------- +Changes to Backend Code Generation +---------------------------------- + +* When lowering calls, only ABI attributes on the call itself are checked, not + the caller. Frontends need to make sure to properly set ABI attributes on + calls (and always should have). + Changes to the ARM Backend -------------------------- diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 53b3bcbb42a..30393298ab7 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -102,29 +102,32 @@ bool TargetLowering::parametersInCSRMatch(const MachineRegisterInfo &MRI, return true; } -/// Set CallLoweringInfo attribute flags based on a call instruction -/// and called function attributes. +/// Set CallLoweringInfo attribute flags based on the call instruction's +/// argument attributes. void TargetLoweringBase::ArgListEntry::setAttributes(const CallBase *Call, unsigned ArgIdx) { - IsSExt = Call->paramHasAttr(ArgIdx, Attribute::SExt); - IsZExt = Call->paramHasAttr(ArgIdx, Attribute::ZExt); - IsInReg = Call->paramHasAttr(ArgIdx, Attribute::InReg); - IsSRet = Call->paramHasAttr(ArgIdx, Attribute::StructRet); - IsNest = Call->paramHasAttr(ArgIdx, Attribute::Nest); - IsByVal = Call->paramHasAttr(ArgIdx, Attribute::ByVal); - IsPreallocated = Call->paramHasAttr(ArgIdx, Attribute::Preallocated); - IsInAlloca = Call->paramHasAttr(ArgIdx, Attribute::InAlloca); - IsReturned = Call->paramHasAttr(ArgIdx, Attribute::Returned); - IsSwiftSelf = Call->paramHasAttr(ArgIdx, Attribute::SwiftSelf); - IsSwiftAsync = Call->paramHasAttr(ArgIdx, Attribute::SwiftAsync); - IsSwiftError = Call->paramHasAttr(ArgIdx, Attribute::SwiftError); - Alignment = Call->getParamStackAlign(ArgIdx); + auto Attrs = Call->getAttributes(); + + IsSExt = Attrs.hasParamAttribute(ArgIdx, Attribute::SExt); + IsZExt = Attrs.hasParamAttribute(ArgIdx, Attribute::ZExt); + IsInReg = Attrs.hasParamAttribute(ArgIdx, Attribute::InReg); + IsSRet = Attrs.hasParamAttribute(ArgIdx, Attribute::StructRet); + IsNest = Attrs.hasParamAttribute(ArgIdx, Attribute::Nest); + IsReturned = Attrs.hasParamAttribute(ArgIdx, Attribute::Returned); + IsSwiftSelf = Attrs.hasParamAttribute(ArgIdx, Attribute::SwiftSelf); + IsSwiftAsync = Attrs.hasParamAttribute(ArgIdx, Attribute::SwiftAsync); + IsSwiftError = Attrs.hasParamAttribute(ArgIdx, Attribute::SwiftError); + Alignment = Attrs.getParamStackAlignment(ArgIdx); + + IsByVal = Attrs.hasParamAttribute(ArgIdx, Attribute::ByVal); ByValType = nullptr; if (IsByVal) { ByValType = Call->getParamByValType(ArgIdx); if (!Alignment) Alignment = Call->getParamAlign(ArgIdx); } + IsInAlloca = Attrs.hasParamAttribute(ArgIdx, Attribute::InAlloca); + IsPreallocated = Attrs.hasParamAttribute(ArgIdx, Attribute::Preallocated); PreallocatedType = nullptr; if (IsPreallocated) PreallocatedType = Call->getParamPreallocatedType(ArgIdx); diff --git a/test/CodeGen/X86/mismatched-byval.ll b/test/CodeGen/X86/mismatched-byval.ll new file mode 100644 index 00000000000..f03e347848c --- /dev/null +++ b/test/CodeGen/X86/mismatched-byval.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s + +; This tests that we only look at the call site for ABI attributes, so f and f2 should codegen differently + +define void @b(i8* byval(i8) %p) { +; CHECK-LABEL: b: +; CHECK: # %bb.0: +; CHECK-NEXT: retq + ret void +} + +define void @f(i8 %p) { +; CHECK-LABEL: f: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $24, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: movb {{[0-9]+}}(%rsp), %al +; CHECK-NEXT: movb %al, (%rsp) +; CHECK-NEXT: callq b@PLT +; CHECK-NEXT: addq $24, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %a = alloca i8 + ;store i8 %p, i8* %a + call void @b(i8* byval(i8) %a) + ret void +} + +define void @f2(i8 %p) { +; CHECK-LABEL: f2: +; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq b@PLT +; CHECK-NEXT: popq %rax +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %a = alloca i8 + ;store i8 %p, i8* %a + call void @b(i8* %a) + ret void +} +