diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 3dabc5ef540cfb..a7fdc3bc40fda0 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1925,11 +1925,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, IsTailCall = false; // Integer args <=32 bits should have an extension attribute. - bool IsInternal = false; - if (auto *G = dyn_cast(Callee)) - if (const Function *Fn = dyn_cast(G->getGlobal())) - IsInternal = isFullyInternal(Fn); - verifyNarrowIntegerArgs(Outs, IsInternal); + verifyNarrowIntegerArgs_Call(Outs, &MF.getFunction(), Callee); // Analyze the operands of the call, assigning locations to each operand. SmallVector ArgLocs; @@ -2192,7 +2188,7 @@ SystemZTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, MachineFunction &MF = DAG.getMachineFunction(); // Integer args <=32 bits should have an extension attribute. - verifyNarrowIntegerArgs(Outs, isFullyInternal(&MF.getFunction())); + verifyNarrowIntegerArgs_Ret(Outs, &MF.getFunction()); // Assign locations to each returned value. SmallVector RetLocs; @@ -9834,23 +9830,74 @@ bool SystemZTargetLowering::isFullyInternal(const Function *Fn) const { return true; } -// Verify that narrow integer arguments are extended as required by the ABI. +static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS) { + FunctionType *FT = F->getFunctionType(); + const AttributeList &Attrs = F->getAttributes(); + if (Attrs.hasRetAttrs()) + OS << Attrs.getAsString(AttributeList::ReturnIndex) << " "; + OS << *F->getReturnType() << " @" << F->getName() << "("; + for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) { + if (I) + OS << ", "; + OS << *FT->getParamType(I); + AttributeSet ArgAttrs = Attrs.getParamAttrs(I); + for (auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt}) + if (ArgAttrs.hasAttribute(A)) + OS << " " << Attribute::getNameFromAttrKind(A); + } + OS << ")\n"; +} + void SystemZTargetLowering:: +verifyNarrowIntegerArgs_Call(const SmallVectorImpl &Outs, + const Function *F, SDValue Callee) const { + bool IsInternal = false; + const Function *CalleeFn = nullptr; + if (auto *G = dyn_cast(Callee)) + if (CalleeFn = dyn_cast(G->getGlobal())) + IsInternal = isFullyInternal(CalleeFn); + if (!verifyNarrowIntegerArgs(Outs, IsInternal)) { + errs() << "ERROR: Missing extension attribute of passed " + << "value in call to function:\n" << "Callee: "; + if (CalleeFn != nullptr) + printFunctionArgExts(CalleeFn, errs()); + else + errs() << "-"; + errs() << "Caller: "; + printFunctionArgExts(F, errs()); + llvm_unreachable(""); + } +} + +void SystemZTargetLowering:: +verifyNarrowIntegerArgs_Ret(const SmallVectorImpl &Outs, + const Function *F) const { + if (!verifyNarrowIntegerArgs(Outs, isFullyInternal(F))) { + errs() << "ERROR: Missing extension attribute of returned " + << "value from function:\n"; + printFunctionArgExts(F, errs()); + llvm_unreachable(""); + } +} + +// Verify that narrow integer arguments are extended as required by the ABI. +// Return false if an error is found. +bool SystemZTargetLowering:: verifyNarrowIntegerArgs(const SmallVectorImpl &Outs, bool IsInternal) const { if (IsInternal || !Subtarget.isTargetELF()) - return; + return true; // Temporarily only do the check when explicitly requested, until it can be // enabled by default. if (!EnableIntArgExtCheck) - return; + return true; if (EnableIntArgExtCheck.getNumOccurrences()) { if (!EnableIntArgExtCheck) - return; + return true; } else if (!getTargetMachine().Options.VerifyArgABICompliance) - return; + return true; for (unsigned i = 0; i < Outs.size(); ++i) { MVT VT = Outs[i].VT; @@ -9858,10 +9905,11 @@ verifyNarrowIntegerArgs(const SmallVectorImpl &Outs, if (VT.isInteger()) { assert((VT == MVT::i32 || VT.getSizeInBits() >= 64) && "Unexpected integer argument VT."); - assert((VT != MVT::i32 || - (Flags.isSExt() || Flags.isZExt() || Flags.isNoExt())) && - "Narrow integer argument must have a valid extension type."); - (void)Flags; + if (VT == MVT::i32 && + !Flags.isSExt() && !Flags.isZExt() && !Flags.isNoExt()) + return false; } } + + return true; } diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h index 8c528897182d17..2b065245c16f20 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -806,7 +806,11 @@ class SystemZTargetLowering : public TargetLowering { const TargetRegisterClass *getRepRegClassFor(MVT VT) const override; bool isFullyInternal(const Function *Fn) const; - void verifyNarrowIntegerArgs(const SmallVectorImpl &Outs, + void verifyNarrowIntegerArgs_Call(const SmallVectorImpl &Outs, + const Function *F, SDValue Callee) const; + void verifyNarrowIntegerArgs_Ret(const SmallVectorImpl &Outs, + const Function *F) const; + bool verifyNarrowIntegerArgs(const SmallVectorImpl &Outs, bool IsInternal) const; }; diff --git a/llvm/test/CodeGen/SystemZ/args-15.ll b/llvm/test/CodeGen/SystemZ/args-15.ll index c810aeb8c46c5d..64217a2a29a6f9 100644 --- a/llvm/test/CodeGen/SystemZ/args-15.ll +++ b/llvm/test/CodeGen/SystemZ/args-15.ll @@ -8,4 +8,6 @@ define i32 @callee_MissingRetAttr() { ret i32 -1 } -; CHECK: Narrow integer argument must have a valid extension type. +; CHECK: ERROR: Missing extension attribute of returned value from function: +; CHECK: i32 @callee_MissingRetAttr() +; CHECK: UNREACHABLE executed diff --git a/llvm/test/CodeGen/SystemZ/args-16.ll b/llvm/test/CodeGen/SystemZ/args-16.ll index b76a2afea50775..846100146e7908 100644 --- a/llvm/test/CodeGen/SystemZ/args-16.ll +++ b/llvm/test/CodeGen/SystemZ/args-16.ll @@ -8,5 +8,7 @@ define i16 @callee_MissingRetAttr() { ret i16 -1 } -; CHECK: Narrow integer argument must have a valid extension type. +; CHECK: ERROR: Missing extension attribute of returned value from function: +; CHECK: i16 @callee_MissingRetAttr() +; CHECK: UNREACHABLE executed diff --git a/llvm/test/CodeGen/SystemZ/args-17.ll b/llvm/test/CodeGen/SystemZ/args-17.ll index bce54b3d2aa1fe..4231d7e9e4772d 100644 --- a/llvm/test/CodeGen/SystemZ/args-17.ll +++ b/llvm/test/CodeGen/SystemZ/args-17.ll @@ -8,4 +8,6 @@ define i8 @callee_MissingRetAttr() { ret i8 -1 } -; CHECK: Narrow integer argument must have a valid extension type. +; CHECK: ERROR: Missing extension attribute of returned value from function: +; CHECK: i8 @callee_MissingRetAttr() +; CHECK: UNREACHABLE executed diff --git a/llvm/test/CodeGen/SystemZ/args-18.ll b/llvm/test/CodeGen/SystemZ/args-18.ll index 82e9729d3a2dfd..bd368fa056c6c9 100644 --- a/llvm/test/CodeGen/SystemZ/args-18.ll +++ b/llvm/test/CodeGen/SystemZ/args-18.ll @@ -11,4 +11,6 @@ define void @caller() { declare void @bar_Struct(i32 %Arg) -; CHECK: Narrow integer argument must have a valid extension type +; CHECK: ERROR: Missing extension attribute of passed value in call to function: +; CHECK: Callee: void @bar_Struct(i32) +; CHECK: Caller: void @caller() diff --git a/llvm/test/CodeGen/SystemZ/args-19.ll b/llvm/test/CodeGen/SystemZ/args-19.ll index 40a794417b4c6f..8b5f421f59fdd8 100644 --- a/llvm/test/CodeGen/SystemZ/args-19.ll +++ b/llvm/test/CodeGen/SystemZ/args-19.ll @@ -11,4 +11,6 @@ define void @caller() { declare void @bar_Struct(i16 %Arg) -; CHECK: Narrow integer argument must have a valid extension type +; CHECK: ERROR: Missing extension attribute of passed value in call to function: +; CHECK: Callee: void @bar_Struct(i16) +; CHECK: Caller: void @caller() diff --git a/llvm/test/CodeGen/SystemZ/args-20.ll b/llvm/test/CodeGen/SystemZ/args-20.ll index ce8b828a2d539a..ed6f2e52bf6ee9 100644 --- a/llvm/test/CodeGen/SystemZ/args-20.ll +++ b/llvm/test/CodeGen/SystemZ/args-20.ll @@ -11,4 +11,6 @@ define void @caller() { declare void @bar_Struct(i8 %Arg) -; CHECK: Narrow integer argument must have a valid extension type +; CHECK: ERROR: Missing extension attribute of passed value in call to function: +; CHECK: Callee: void @bar_Struct(i8) +; CHECK: Caller: void @caller() diff --git a/llvm/test/CodeGen/SystemZ/args-21.ll b/llvm/test/CodeGen/SystemZ/args-21.ll index c64233094c7df9..da5c8fe5ffc7fc 100644 --- a/llvm/test/CodeGen/SystemZ/args-21.ll +++ b/llvm/test/CodeGen/SystemZ/args-21.ll @@ -16,4 +16,6 @@ define void @foo() { ret void } -; CHECK: Narrow integer argument must have a valid extension type +; CHECK: ERROR: Missing extension attribute of returned value from function: +; CHECK: i32 @bar(i32) +; CHECK: UNREACHABLE executed