diff options
author | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2015-11-17 16:45:40 +0000 |
---|---|---|
committer | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2015-11-17 16:45:40 +0000 |
commit | 88ddeae8bda08376ddb05e47c5e5ca6f83454131 (patch) | |
tree | ec4d2f1d6d7b7439fda0cd2f03dbbd7945004d8a | |
parent | af08e1bdf053f0a4e385bd2889d06ce546f514de (diff) | |
download | bcm5719-llvm-88ddeae8bda08376ddb05e47c5e5ca6f83454131.tar.gz bcm5719-llvm-88ddeae8bda08376ddb05e47c5e5ca6f83454131.zip |
[AArch64] Promote f16 SELECT_CC CC operands when op is legal.
SELECT_CC has the nasty property of having operands with unrelated
types. So if you do something like:
f32 = select_cc f16, f16, f32, f32, cc
You'd only look for the action for <select_cc, f32>, but never f16.
If the types are all legal, but the op isn't (as for f16 on AArch64,
or for f128 on x86_64/AArch64?), then you get into trouble.
For f128, we have softenSetCCOperands to handle this case.
Similarly, for f16, we can directly promote the CC operands.
llvm-svn: 253344
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/f16-instructions.ll | 27 |
2 files changed, 34 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 14d2f6fb61a..26f03ef765d 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3887,7 +3887,13 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS, } } - // Handle integers first. + // Also handle f16, for which we need to do a f32 comparison. + if (LHS.getValueType() == MVT::f16) { + LHS = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f32, LHS); + RHS = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f32, RHS); + } + + // Next, handle integers. if (LHS.getValueType().isInteger()) { assert((LHS.getValueType() == RHS.getValueType()) && (LHS.getValueType() == MVT::i32 || LHS.getValueType() == MVT::i64)); diff --git a/llvm/test/CodeGen/AArch64/f16-instructions.ll b/llvm/test/CodeGen/AArch64/f16-instructions.ll index 3dd54e64623..ee862850aca 100644 --- a/llvm/test/CodeGen/AArch64/f16-instructions.ll +++ b/llvm/test/CodeGen/AArch64/f16-instructions.ll @@ -143,6 +143,33 @@ define half @test_select_cc(half %a, half %b, half %c, half %d) #0 { ret half %r } +; CHECK-LABEL: test_select_cc_f32_f16: +; CHECK-DAG: fcvt s2, h2 +; CHECK-DAG: fcvt s3, h3 +; CHECK-NEXT: fcmp s2, s3 +; CHECK-NEXT: fcsel s0, s0, s1, ne +; CHECK-NEXT: ret +define float @test_select_cc_f32_f16(float %a, float %b, half %c, half %d) #0 { + %cc = fcmp une half %c, %d + %r = select i1 %cc, float %a, float %b + ret float %r +} + +; CHECK-LABEL: test_select_cc_f16_f32: +; CHECK-DAG: fcvt s0, h0 +; CHECK-DAG: fcvt s1, h1 +; CHECK-DAG: fcmp s2, s3 +; CHECK-DAG: cset w8, ne +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: fcsel s0, s0, s1, ne +; CHECK-NEXT: fcvt h0, s0 +; CHECK-NEXT: ret +define half @test_select_cc_f16_f32(half %a, half %b, float %c, float %d) #0 { + %cc = fcmp une float %c, %d + %r = select i1 %cc, half %a, half %b + ret half %r +} + ; CHECK-LABEL: test_fcmp_une: ; CHECK-NEXT: fcvt s1, h1 ; CHECK-NEXT: fcvt s0, h0 |