From 54136cad2ea9f322849ce49b299860454fc97368 Mon Sep 17 00:00:00 2001 From: Kevin Qin Date: Fri, 14 Feb 2014 09:41:15 +0000 Subject: [PATCH] [AArch64 NEON] Fix a bug to avoid using floating type as condition type in lowering SELECT_CC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201395 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 17 ++++++----------- test/CodeGen/AArch64/neon-select_cc.ll | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index c7aa753f6c6..c76fec3d34d 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3036,6 +3036,8 @@ static SDValue LowerVectorSELECT_CC(SDValue Op, SelectionDAG &DAG) { SDValue RHS = Op.getOperand(1); SDValue IfTrue = Op.getOperand(2); SDValue IfFalse = Op.getOperand(3); + EVT IfTrueVT = IfTrue.getValueType(); + EVT CondVT = IfTrueVT.changeVectorElementTypeToInteger(); ISD::CondCode CC = cast(Op.getOperand(4))->get(); // If LHS & RHS are floating point and IfTrue & IfFalse are vectors, we will @@ -3060,11 +3062,6 @@ static SDValue LowerVectorSELECT_CC(SDValue Op, SelectionDAG &DAG) { SDValue VSetCC = DAG.getSetCC(dl, CVT, LHS, RHS, CC); SDValue ResCC = LowerVectorSETCC(VSetCC, DAG); - EVT IfTrueVT = IfTrue.getValueType(); - EVT CastEltT = - MVT::getIntegerVT(IfTrueVT.getVectorElementType().getSizeInBits()); - EVT CastVT = EVT::getVectorVT(*DAG.getContext(), CastEltT, - IfTrueVT.getVectorNumElements()); if (CEltT.getSizeInBits() < IfTrueVT.getSizeInBits()) { EVT DUPVT = EVT::getVectorVT(*DAG.getContext(), CEltT, @@ -3072,7 +3069,7 @@ static SDValue LowerVectorSELECT_CC(SDValue Op, SelectionDAG &DAG) { ResCC = DAG.getNode(AArch64ISD::NEON_VDUPLANE, dl, DUPVT, ResCC, DAG.getConstant(0, MVT::i64, false)); - ResCC = DAG.getNode(ISD::BITCAST, dl, CastVT, ResCC); + ResCC = DAG.getNode(ISD::BITCAST, dl, CondVT, ResCC); } else { // FIXME: If IfTrue & IfFalse hold v1i8, v1i16 or v1i32, this function // can't handle them and will hit this assert. @@ -3084,7 +3081,7 @@ static SDValue LowerVectorSELECT_CC(SDValue Op, SelectionDAG &DAG) { EVT ExVT = EVT::getVectorVT(*DAG.getContext(), CEltT, ExEltNum); ResCC = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ExVT, ResCC, DAG.getConstant(0, MVT::i64, false)); - ResCC = DAG.getNode(ISD::BITCAST, dl, CastVT, ResCC); + ResCC = DAG.getNode(ISD::BITCAST, dl, CondVT, ResCC); } SDValue VSelect = DAG.getNode(ISD::VSELECT, dl, IfTrue.getValueType(), ResCC, IfTrue, IfFalse); @@ -3113,11 +3110,9 @@ static SDValue LowerVectorSELECT_CC(SDValue Op, SelectionDAG &DAG) { } SDValue VDup; if (IfTrue.getValueType().getVectorNumElements() == 1) - VDup = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, IfTrue.getValueType(), - A64SELECT_CC); + VDup = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, CondVT, A64SELECT_CC); else - VDup = DAG.getNode(AArch64ISD::NEON_VDUP, dl, IfTrue.getValueType(), - A64SELECT_CC); + VDup = DAG.getNode(AArch64ISD::NEON_VDUP, dl, CondVT, A64SELECT_CC); SDValue VSelect = DAG.getNode(ISD::VSELECT, dl, IfTrue.getValueType(), VDup, IfTrue, IfFalse); return VSelect; diff --git a/test/CodeGen/AArch64/neon-select_cc.ll b/test/CodeGen/AArch64/neon-select_cc.ll index 537ec97d368..f6b5d3ca57d 100644 --- a/test/CodeGen/AArch64/neon-select_cc.ll +++ b/test/CodeGen/AArch64/neon-select_cc.ll @@ -160,6 +160,17 @@ define <4x float> @test_select_cc_v4f32(float %a, float %b, <4x float> %c, <4x f ret <4x float> %e } +define <4x float> @test_select_cc_v4f32_icmp(i32 %a, i32 %b, <4x float> %c, <4x float> %d ) { +; CHECK-LABEL: test_select_cc_v4f32_icmp: +; CHECK: cmp w0, w1, uxtw +; CHECK: csinv w0, wzr, wzr, ne +; CHECK-NEXT: dup v{{[0-9]+}}.4s, w0 +; CHECK-NEXT: bsl v{{[0-9]+}}.16b, v0.16b, v1.16b + %cmp31 = icmp eq i32 %a, %b + %e = select i1 %cmp31, <4x float> %c, <4x float> %d + ret <4x float> %e +} + define <1 x double> @test_select_cc_v1f64(double %a, double %b, <1 x double> %c, <1 x double> %d ) { ; CHECK-LABEL: test_select_cc_v1f64: ; CHECK: fcmeq v{{[0-9]+}}.2d, v0.2d, v1.2d @@ -169,6 +180,17 @@ define <1 x double> @test_select_cc_v1f64(double %a, double %b, <1 x double> %c, ret <1 x double> %e } +define <1 x double> @test_select_cc_v1f64_icmp(i64 %a, i64 %b, <1 x double> %c, <1 x double> %d ) { +; CHECK-LABEL: test_select_cc_v1f64_icmp: +; CHECK: cmp x0, x1 +; CHECK-NEXT: csinv x0, xzr, xzr, ne +; CHECK-NEXT: fmov d{{[0-9]+}}, x0 +; CHECK-NEXT: bsl v{{[0-9]+}}.8b, v0.8b, v1.8b + %cmp31 = icmp eq i64 %a, %b + %e = select i1 %cmp31, <1 x double> %c, <1 x double> %d + ret <1 x double> %e +} + define <2 x double> @test_select_cc_v2f64(double %a, double %b, <2 x double> %c, <2 x double> %d ) { ; CHECK-LABEL: test_select_cc_v2f64: ; CHECK: fcmeq v{{[0-9]+}}.2d, v0.2d, v1.2d -- 2.34.1