Skip to content

Commit

Permalink
[X86] Fix LowerAsmOutputForConstraint.
Browse files Browse the repository at this point in the history
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

llvm-svn: 354163
  • Loading branch information
niravhdave committed Feb 15, 2019
1 parent c1648f2 commit 7875841
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 12 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/TargetLowering.h
Expand Up @@ -3663,7 +3663,7 @@ class TargetLowering : public TargetLoweringBase {
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;
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Expand Up @@ -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:
Expand All @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Expand Up @@ -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();
}
Expand Down
13 changes: 6 additions & 7 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -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)
Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86ISelLowering.h
Expand Up @@ -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;

Expand Down
19 changes: 19 additions & 0 deletions llvm/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
}

0 comments on commit 7875841

Please sign in to comment.