From 45ef910a2640d5b127d2a4fe7cca80eb142af03f Mon Sep 17 00:00:00 2001 From: Nirav Dave Date: Fri, 15 Feb 2019 20:01:55 +0000 Subject: [PATCH] [X86] Fix LowerAsmOutputForConstraint. Summary: Update Flag when generating cc output. Fixes PR40737. Reviewers: rnk, nickdesaulniers, craig.topper, spatel Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58283 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354163 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/TargetLowering.h | 2 +- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 3 +-- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 +- lib/Target/X86/X86ISelLowering.cpp | 13 ++++++------- lib/Target/X86/X86ISelLowering.h | 2 +- test/CodeGen/X86/pr40737.ll | 19 +++++++++++++++++++ 6 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 test/CodeGen/X86/pr40737.ll diff --git a/include/llvm/CodeGen/TargetLowering.h b/include/llvm/CodeGen/TargetLowering.h index fa71024a25f..70fb2f5d279 100644 --- a/include/llvm/CodeGen/TargetLowering.h +++ b/include/llvm/CodeGen/TargetLowering.h @@ -3663,7 +3663,7 @@ public: SelectionDAG &DAG) const; // Lower custom output constraints. If invalid, return SDValue(). - virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue *Flag, + virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, SDLoc DL, const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c6338383bbd..75f7cc08aa9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8174,7 +8174,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { DAG, FuncInfo, getCurSDLoc(), Chain, &Flag, CS.getInstruction()); break; case TargetLowering::C_Other: - Val = TLI.LowerAsmOutputForConstraint(Chain, &Flag, getCurSDLoc(), + Val = TLI.LowerAsmOutputForConstraint(Chain, Flag, getCurSDLoc(), OpInfo, DAG); break; case TargetLowering::C_Memory: @@ -8185,7 +8185,6 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { // Indirect output manifest as stores. Record output chains. if (OpInfo.isIndirect) { - const Value *Ptr = OpInfo.CallOperandVal; assert(Ptr && "Expected value CallOperandVal for indirect asm operand"); SDValue Store = DAG.getStore(Chain, getCurSDLoc(), Val, getValue(Ptr), diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index ad2e5e848d3..143845f8aa1 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3280,7 +3280,7 @@ const char *TargetLowering::LowerXConstraint(EVT ConstraintVT) const { } SDValue TargetLowering::LowerAsmOutputForConstraint( - SDValue &Chain, SDValue *Flag, SDLoc DL, const AsmOperandInfo &OpInfo, + SDValue &Chain, SDValue &Flag, SDLoc DL, const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const { return SDValue(); } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 47c608dbabd..54e8251d7c3 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -42733,7 +42733,7 @@ LowerXConstraint(EVT ConstraintVT) const { // Lower @cc targets via setcc. SDValue X86TargetLowering::LowerAsmOutputForConstraint( - SDValue &Chain, SDValue *Flag, SDLoc DL, const AsmOperandInfo &OpInfo, + SDValue &Chain, SDValue &Flag, SDLoc DL, const AsmOperandInfo &OpInfo, SelectionDAG &DAG) const { X86::CondCode Cond = parseConstraintCode(OpInfo.ConstraintCode); if (Cond == X86::COND_INVALID) @@ -42744,14 +42744,13 @@ SDValue X86TargetLowering::LowerAsmOutputForConstraint( report_fatal_error("Flag output operand is of invalid type"); // Get EFLAGS register. Only update chain when copyfrom is glued. - SDValue EFlags; - if (Flag) { - EFlags = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32, *Flag); - Chain = EFlags.getValue(1); + if (Flag.getNode()) { + Flag = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32, Flag); + Chain = Flag.getValue(1); } else - EFlags = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32); + Flag = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32); // Extract CC code. - SDValue CC = getSETCC(Cond, EFlags, DL, DAG); + SDValue CC = getSETCC(Cond, Flag, DL, DAG); // Extend to 32-bits SDValue Result = DAG.getNode(ISD::ZERO_EXTEND, DL, OpInfo.ConstraintVT, CC); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 45d73085259..a328b954c23 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -922,7 +922,7 @@ namespace llvm { } /// Handle Lowering flag assembly outputs. - SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue *Flag, SDLoc DL, + SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, SDLoc DL, const AsmOperandInfo &Constraint, SelectionDAG &DAG) const override; diff --git a/test/CodeGen/X86/pr40737.ll b/test/CodeGen/X86/pr40737.ll new file mode 100644 index 00000000000..2643b78936a --- /dev/null +++ b/test/CodeGen/X86/pr40737.ll @@ -0,0 +1,19 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -o - | FileCheck %s + +define i8 @_BitScanForward(i32* nocapture %Index, i32 %Mask) { +; CHECK-LABEL: _BitScanForward: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: bsfl %esi, %ecx +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: setne %al +; CHECK-NEXT: movl %ecx, (%rdi) +; CHECK-NEXT: retq +entry: + %0 = tail call { i8, i32 } asm "bsf$(l $2,$1 $| $1,$2$)", "={@ccnz},=r,r,~{dirflag},~{fpsr},~{flags}"(i32 %Mask) + %asmresult = extractvalue { i8, i32 } %0, 0 + %asmresult1 = extractvalue { i8, i32 } %0, 1 + store i32 %asmresult1, i32* %Index, align 4 + ret i8 %asmresult +} -- 2.11.0