Files
clang-p2996/llvm/test/CodeGen/RISCV/float-br-fcmp.ll
Shiva Chen d58bd8dc4a [RISCV] Expand function call to "call" pseudoinstruction
To do this:
1. Change GlobalAddress SDNode to TargetGlobalAddress to avoid legalizer
   split the symbol.

2. Change ExternalSymbol SDNode to TargetExternalSymbol to avoid legalizer
   split the symbol.

3. Let PseudoCALL match direct call with target operand TargetGlobalAddress
   and TargetExternalSymbol.

Differential Revision: https://reviews.llvm.org/D44885

llvm-svn: 330827
2018-04-25 14:19:12 +00:00

495 lines
14 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32IF %s
declare void @abort()
declare void @exit(i32)
declare float @dummy(float)
define void @br_fcmp_false(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_false:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: addi a0, zero, 1
; RV32IF-NEXT: bnez a0, .LBB0_2
; RV32IF-NEXT: # %bb.1: # %if.then
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB0_2: # %if.else
; RV32IF-NEXT: call abort
%1 = fcmp false float %a, %b
br i1 %1, label %if.then, label %if.else
if.then:
ret void
if.else:
tail call void @abort()
unreachable
}
define void @br_fcmp_oeq(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_oeq:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: feq.s a0, ft1, ft0
; RV32IF-NEXT: bnez a0, .LBB1_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB1_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp oeq float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
; TODO: generated code quality for this is very poor due to
; DAGCombiner::visitXOR converting the legal setoeq to setune, which requires
; expansion.
define void @br_fcmp_oeq_alt(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_oeq_alt:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: feq.s a0, ft1, ft0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: beqz a0, .LBB2_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB2_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp oeq float %a, %b
br i1 %1, label %if.then, label %if.else
if.then:
tail call void @abort()
unreachable
if.else:
ret void
}
define void @br_fcmp_ogt(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ogt:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: flt.s a0, ft1, ft0
; RV32IF-NEXT: bnez a0, .LBB3_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB3_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ogt float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_oge(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_oge:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: fle.s a0, ft1, ft0
; RV32IF-NEXT: bnez a0, .LBB4_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB4_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp oge float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_olt(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_olt:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: flt.s a0, ft1, ft0
; RV32IF-NEXT: bnez a0, .LBB5_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB5_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp olt float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_ole(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ole:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: fle.s a0, ft1, ft0
; RV32IF-NEXT: bnez a0, .LBB6_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB6_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ole float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
; TODO: feq.s+sltiu+bne -> feq.s+beq
define void @br_fcmp_one(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_one:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: feq.s a0, ft1, ft1
; RV32IF-NEXT: feq.s a1, ft0, ft0
; RV32IF-NEXT: and a0, a1, a0
; RV32IF-NEXT: feq.s a1, ft0, ft1
; RV32IF-NEXT: not a1, a1
; RV32IF-NEXT: seqz a0, a0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: and a0, a1, a0
; RV32IF-NEXT: bnez a0, .LBB7_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB7_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp one float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_ord(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ord:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: feq.s a1, ft0, ft0
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: feq.s a0, ft0, ft0
; RV32IF-NEXT: and a0, a0, a1
; RV32IF-NEXT: seqz a0, a0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: bnez a0, .LBB8_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB8_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ord float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_ueq(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ueq:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: feq.s a0, ft1, ft0
; RV32IF-NEXT: feq.s a1, ft0, ft0
; RV32IF-NEXT: feq.s a2, ft1, ft1
; RV32IF-NEXT: and a1, a2, a1
; RV32IF-NEXT: seqz a1, a1
; RV32IF-NEXT: or a0, a0, a1
; RV32IF-NEXT: bnez a0, .LBB9_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB9_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ueq float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_ugt(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ugt:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: fle.s a0, ft1, ft0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: bnez a0, .LBB10_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB10_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ugt float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_uge(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_uge:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: flt.s a0, ft1, ft0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: bnez a0, .LBB11_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB11_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp uge float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_ult(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ult:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: fle.s a0, ft1, ft0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: bnez a0, .LBB12_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB12_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ult float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_ule(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_ule:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: flt.s a0, ft1, ft0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: bnez a0, .LBB13_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB13_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp ule float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_une(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_une:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: feq.s a0, ft1, ft0
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: bnez a0, .LBB14_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB14_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp une float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_uno(float %a, float %b) nounwind {
; TODO: sltiu+bne -> beq
; RV32IF-LABEL: br_fcmp_uno:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: feq.s a1, ft0, ft0
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: feq.s a0, ft0, ft0
; RV32IF-NEXT: and a0, a0, a1
; RV32IF-NEXT: seqz a0, a0
; RV32IF-NEXT: bnez a0, .LBB15_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB15_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp uno float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
define void @br_fcmp_true(float %a, float %b) nounwind {
; RV32IF-LABEL: br_fcmp_true:
; RV32IF: # %bb.0:
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: addi a0, zero, 1
; RV32IF-NEXT: bnez a0, .LBB16_2
; RV32IF-NEXT: # %bb.1: # %if.else
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB16_2: # %if.then
; RV32IF-NEXT: call abort
%1 = fcmp true float %a, %b
br i1 %1, label %if.then, label %if.else
if.else:
ret void
if.then:
tail call void @abort()
unreachable
}
; This test exists primarily to trigger RISCVInstrInfo::storeRegToStackSlot
; and RISCVInstrInfo::loadRegFromStackSlot
define i32 @br_fcmp_store_load_stack_slot(float %a, float %b) nounwind {
; TODO: addi %lo(.LCPI17_0) should be merged in to the following flw
; RV32IF-LABEL: br_fcmp_store_load_stack_slot:
; RV32IF: # %bb.0: # %entry
; RV32IF-NEXT: addi sp, sp, -16
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: mv a0, zero
; RV32IF-NEXT: call dummy
; RV32IF-NEXT: lui a1, %hi(.LCPI17_0)
; RV32IF-NEXT: addi a1, a1, %lo(.LCPI17_0)
; RV32IF-NEXT: flw ft1, 0(a1)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fsw ft1, 8(sp)
; RV32IF-NEXT: feq.s a0, ft0, ft1
; RV32IF-NEXT: beqz a0, .LBB17_3
; RV32IF-NEXT: # %bb.1: # %if.end
; RV32IF-NEXT: mv a0, zero
; RV32IF-NEXT: call dummy
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: flw ft1, 8(sp)
; RV32IF-NEXT: feq.s a0, ft0, ft1
; RV32IF-NEXT: beqz a0, .LBB17_3
; RV32IF-NEXT: # %bb.2: # %if.end4
; RV32IF-NEXT: mv a0, zero
; RV32IF-NEXT: lw ra, 12(sp)
; RV32IF-NEXT: addi sp, sp, 16
; RV32IF-NEXT: ret
; RV32IF-NEXT: .LBB17_3: # %if.then
; RV32IF-NEXT: call abort
entry:
%call = call float @dummy(float 0.000000e+00)
%cmp = fcmp une float %call, 0.000000e+00
br i1 %cmp, label %if.then, label %if.end
if.then:
call void @abort()
unreachable
if.end:
%call1 = call float @dummy(float 0.000000e+00)
%cmp2 = fcmp une float %call1, 0.000000e+00
br i1 %cmp2, label %if.then3, label %if.end4
if.then3:
call void @abort()
unreachable
if.end4:
ret i32 0
}