summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/LangRef.html5
-rw-r--r--include/llvm/Target/TargetLowering.h11
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp7
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp9
-rw-r--r--lib/Target/X86/X86ISelLowering.h3
-rw-r--r--test/CodeGen/X86/bool-zext.ll18
6 files changed, 43 insertions, 10 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 893876620a..ab9f1caae6 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -1017,8 +1017,9 @@ declare signext i8 @returns_signed_char()
<dl>
<dt><tt><b>zeroext</b></tt></dt>
<dd>This indicates to the code generator that the parameter or return value
- should be zero-extended to a 32-bit value by the caller (for a parameter)
- or the callee (for a return value).</dd>
+ should be zero-extended to the extent required by the target's ABI (which
+ is usually 32-bits, but is 8-bits for a i1 on x86-64) by the caller (for a
+ parameter) or the callee (for a return value).</dd>
<dt><tt><b>signext</b></tt></dt>
<dd>This indicates to the code generator that the parameter or return value
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 618ed54894..f257b035b8 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -1287,6 +1287,17 @@ public:
return false;
}
+ /// getTypeForExtendedInteger - Return the type that should be used to zero or
+ /// sign extend a zeroext/signext integer argument or return value.
+ /// FIXME: Most C calling convention requires the return type to be promoted,
+ /// but this is not true all the time, e.g. i1 on x86-64. It is also not
+ /// necessary for non-C calling conventions. The frontend should handle this
+ /// and include all of the necessary information.
+ virtual MVT
+ getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const {
+ return MVT::i32;
+ }
+
/// LowerOperationWrapper - This callback is invoked by the type legalizer
/// to legalize nodes with an illegal operand type but legal result types.
/// It replaces the LowerOperation callback in the type Legalizer.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index aa7009ac39..5548318835 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1128,12 +1128,9 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
else if (F->paramHasAttr(0, Attribute::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
- // FIXME: C calling convention requires the return type to be promoted
- // to at least 32-bit. But this is not necessary for non-C calling
- // conventions. The frontend should mark functions whose return values
- // require promoting with signext or zeroext attributes.
if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger()) {
- EVT MinVT = TLI.getRegisterType(*DAG.getContext(), MVT::i32);
+ MVT ReturnMVT = TLI.getTypeForExtendedInteger(VT, ExtendKind);
+ EVT MinVT = TLI.getRegisterType(*DAG.getContext(), ReturnMVT);
if (VT.bitsLT(MinVT))
VT = MinVT;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 910ed2abd1..c1aa7200be 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1448,6 +1448,15 @@ bool X86TargetLowering::isUsedByReturnOnly(SDNode *N) const {
return HasRet;
}
+MVT
+X86TargetLowering::getTypeForExtendedInteger(EVT VT,
+ ISD::NodeType ExtendKind) const {
+ // TODO: Is this also valid on 32-bit?
+ if (Subtarget->is64Bit() && VT == MVT::i1 && ExtendKind == ISD::ZERO_EXTEND)
+ return MVT::i8;
+ return MVT::i32;
+}
+
/// LowerCallResult - Lower the result values of a call into the
/// appropriate copies out of appropriate physical registers.
///
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 551884b18e..0857c594b4 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -843,6 +843,9 @@ namespace llvm {
virtual bool isUsedByReturnOnly(SDNode *N) const;
+ virtual MVT
+ getTypeForExtendedInteger(EVT VT, ISD::NodeType ExtendKind) const;
+
virtual bool
CanLowerReturn(CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
diff --git a/test/CodeGen/X86/bool-zext.ll b/test/CodeGen/X86/bool-zext.ll
index 67168d4bf0..d2c30c64f2 100644
--- a/test/CodeGen/X86/bool-zext.ll
+++ b/test/CodeGen/X86/bool-zext.ll
@@ -6,7 +6,7 @@
define void @bar1(i1 zeroext %v1) nounwind ssp {
entry:
%conv = zext i1 %v1 to i32
- %call = tail call i32 (...)* @foo(i32 %conv) nounwind
+ %call = tail call i32 (...)* @foo1(i32 %conv) nounwind
ret void
}
@@ -16,8 +16,20 @@ entry:
define void @bar2(i8 zeroext %v1) nounwind ssp {
entry:
%conv = zext i8 %v1 to i32
- %call = tail call i32 (...)* @foo(i32 %conv) nounwind
+ %call = tail call i32 (...)* @foo1(i32 %conv) nounwind
ret void
}
-declare i32 @foo(...)
+; CHECK: @bar3
+; CHECK: callq
+; CHECK-NOT: movzbl
+; CHECK-NOT: and
+; CHECK: ret
+define zeroext i1 @bar3() nounwind ssp {
+entry:
+ %call = call i1 @foo2() nounwind
+ ret i1 %call
+}
+
+declare i32 @foo1(...)
+declare zeroext i1 @foo2()