aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp25
-rw-r--r--test/CodeGen/X86/trunc-to-bool.ll11
2 files changed, 16 insertions, 20 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 9bd8bb5..a4be03a 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -267,7 +267,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
// matter in theory which one we pick, but this tends to give better code?
unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
SDValue Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT),
- SDValue(N, 0));
+ SDValue(N, 0));
assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
return Result;
}
@@ -350,22 +350,27 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
}
SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
- unsigned NewOpc = N->getOpcode();
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ unsigned NewOpc = N->getOpcode();
// If we're promoting a UINT to a larger size, check to see if the new node
// will be legal. If it isn't, check to see if FP_TO_SINT is legal, since
// we can use that instead. This allows us to generate better code for
// FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
// legal, such as PowerPC.
- if (N->getOpcode() == ISD::FP_TO_UINT) {
- if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
- (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
- TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom))
- NewOpc = ISD::FP_TO_SINT;
- }
-
- return DAG.getNode(NewOpc, NVT, N->getOperand(0));
+ if (N->getOpcode() == ISD::FP_TO_UINT &&
+ !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
+ TLI.isOperationLegal(ISD::FP_TO_SINT, NVT))
+ NewOpc = ISD::FP_TO_SINT;
+
+ SDValue Res = DAG.getNode(NewOpc, NVT, N->getOperand(0));
+
+ // Assert that the converted value fits in the original type. If it doesn't
+ // (eg: because the value being converted is too big), then the result of the
+ // original operation was undefined anyway, so the assert is still correct.
+ return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ?
+ ISD::AssertZext : ISD::AssertSext,
+ NVT, Res, DAG.getValueType(N->getValueType(0)));
}
SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
diff --git a/test/CodeGen/X86/trunc-to-bool.ll b/test/CodeGen/X86/trunc-to-bool.ll
index 9dd1425..25a1191 100644
--- a/test/CodeGen/X86/trunc-to-bool.ll
+++ b/test/CodeGen/X86/trunc-to-bool.ll
@@ -2,7 +2,7 @@
; sure only the LSBit survives. Test that this is the case both for a returned
; value and as the operand of a branch.
; RUN: llvm-as < %s | llc -march=x86 | grep {\\(and\\)\\|\\(test.*\\\$1\\)} | \
-; RUN: count 6
+; RUN: count 5
define i1 @test1(i32 %X) zeroext {
%Y = trunc i32 %X to i1
@@ -40,15 +40,6 @@ cond_false:
ret i32 42
}
-define i32 @test5(float %f) {
- %tmp = fptoui float %f to i1
- br i1 %tmp, label %cond_true, label %cond_false
-cond_true:
- ret i32 21
-cond_false:
- ret i32 42
-}
-
define i32 @test6(double %d) {
%tmp = fptosi double %d to i1
br i1 %tmp, label %cond_true, label %cond_false