diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1242,7 +1242,7 @@ LLVM_DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG); dbgs() << "\n"); SDValue Res = SDValue(); - + bool ReplaceChain = false; if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) { LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n"); return false; @@ -1279,7 +1279,10 @@ case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; - case ISD::STRICT_SINT_TO_FP: Res = PromoteIntOp_STRICT_SINT_TO_FP(N); break; + case ISD::STRICT_SINT_TO_FP: + ReplaceChain = true; + Res = PromoteIntOp_STRICT_SINT_TO_FP(N); + break; case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), OpNo); break; case ISD::MSTORE: Res = PromoteIntOp_MSTORE(cast(N), @@ -1293,7 +1296,10 @@ case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; case ISD::FP16_TO_FP: case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; - case ISD::STRICT_UINT_TO_FP: Res = PromoteIntOp_STRICT_UINT_TO_FP(N); break; + case ISD::STRICT_UINT_TO_FP: + ReplaceChain = true; + Res = PromoteIntOp_STRICT_UINT_TO_FP(N); + break; case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; case ISD::EXTRACT_SUBVECTOR: Res = PromoteIntOp_EXTRACT_SUBVECTOR(N); break; @@ -1339,10 +1345,16 @@ if (Res.getNode() == N) return true; - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + assert(Res.getValueType() == N->getValueType(0) && + N->getNumValues() == (ReplaceChain ? 2 : 1) && "Invalid operand expansion"); + LLVM_DEBUG(dbgs() << "Replacing: "; N->dump(&DAG); dbgs() << " with: "; + Res.dump()); ReplaceValueWith(SDValue(N, 0), Res); + if (ReplaceChain) + ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1)); + return false; } diff --git a/llvm/test/CodeGen/AArch64/strict-fp-int-promote.mir b/llvm/test/CodeGen/AArch64/strict-fp-int-promote.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/strict-fp-int-promote.mir @@ -0,0 +1,76 @@ +# RUN: llc -O0 -simplify-mir --start-after=aarch64-prelegalizer-combiner -o - %s | FileCheck %s +--- | + target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + target triple = "aarch64-arm-none-eabi" + define i32 @test() #0 { + entry: + %conv = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 1, metadata !"round.tonearest", metadata !"fpexcept.strict") #3 + %conv1 = call float @llvm.experimental.constrained.sitofp.f32.i16(i16 1, metadata !"round.tonearest", metadata !"fpexcept.strict") #3 + %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %conv, float %conv1, metadata !"oeq", metadata !"fpexcept.strict") #3 + %conv2 = zext i1 %cmp to i32 + ret i32 %conv2 + } + declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) #1 + declare float @llvm.experimental.constrained.sitofp.f32.i16(i16, metadata, metadata) #1 + declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata) #1 + declare void @llvm.stackprotector(i8*, i8**) #2 + attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + attributes #1 = { inaccessiblememonly nounwind willreturn } + attributes #2 = { nounwind } + attributes #3 = { strictfp } +... +--- +name: test +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: true +tracksRegLiveness: true +hasWinCFI: false +registers: + - { id: 0, class: _, preferred-register: '' } + - { id: 1, class: _, preferred-register: '' } +liveins: [] +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 4294967295 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0: + successors: %bb.1(0x80000000) + + %1:_(s32) = G_CONSTANT i32 1 + + bb.1.entry: + %0:_(s32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.experimental.constrained.sitofp), %1(s32) + +... +# This test checks that we generate output +# CHECK-LABEL: test: // @test +# CHECK: mov w8, #1 +# CHECK-NEXT: scvtf s0, w8 +# CHECK-NEXT: fcmp s0, s0 +# CHECK-NEXT: cset w0, eq +# CHECK-NEXT: ret