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);
--- /dev/null
+; 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
+}
+