462 lines
13 KiB
LLVM
462 lines
13 KiB
LLVM
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||
|
; RUN: llc -mtriple=riscv64 -mattr=+c -verify-machineinstrs < %s \
|
||
|
; RUN: | FileCheck -check-prefix=NOCMOV %s
|
||
|
; RUN: llc -mtriple=riscv64 -mattr=+conditional-cmv-fusion,+c -verify-machineinstrs < %s \
|
||
|
; RUN: | FileCheck -check-prefixes=CMOV,CMOV-NOZICOND %s
|
||
|
; RUN: llc -mtriple=riscv64 -mattr=+conditional-cmv-fusion,+c,+zicond -verify-machineinstrs < %s \
|
||
|
; RUN: | FileCheck -check-prefixes=CMOV,CMOV-ZICOND %s
|
||
|
; RUN: llc -mtriple=riscv64 -mattr=+short-forward-branch-opt -verify-machineinstrs < %s \
|
||
|
; RUN: | FileCheck -check-prefixes=SHORT_FORWARD,SFB-NOZICOND %s
|
||
|
; RUN: llc -mtriple=riscv64 -mattr=+short-forward-branch-opt,+c -verify-machineinstrs < %s \
|
||
|
; RUN: | FileCheck -check-prefixes=SHORT_FORWARD,SFB-NOZICOND %s
|
||
|
; RUN: llc -mtriple=riscv64 -mattr=+short-forward-branch-opt,+zicond -verify-machineinstrs < %s \
|
||
|
; RUN: | FileCheck -check-prefixes=SHORT_FORWARD,SFB-ZICOND %s
|
||
|
|
||
|
; The conditional move optimization in sifive-p450 requires that only a
|
||
|
; single c.mv instruction appears in the branch shadow.
|
||
|
|
||
|
; The sifive-7-series can predicate an xor.
|
||
|
|
||
|
define signext i32 @test1(i32 signext %x, i32 signext %y, i32 signext %z) {
|
||
|
; NOCMOV-LABEL: test1:
|
||
|
; NOCMOV: # %bb.0:
|
||
|
; NOCMOV-NEXT: snez a2, a2
|
||
|
; NOCMOV-NEXT: addi a2, a2, -1
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: test1:
|
||
|
; CMOV: # %bb.0:
|
||
|
; CMOV-NEXT: xor a1, a1, a0
|
||
|
; CMOV-NEXT: bnez a2, .LBB0_2
|
||
|
; CMOV-NEXT: # %bb.1:
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB0_2:
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SHORT_FORWARD-LABEL: test1:
|
||
|
; SHORT_FORWARD: # %bb.0:
|
||
|
; SHORT_FORWARD-NEXT: bnez a2, .LBB0_2
|
||
|
; SHORT_FORWARD-NEXT: # %bb.1:
|
||
|
; SHORT_FORWARD-NEXT: xor a0, a0, a1
|
||
|
; SHORT_FORWARD-NEXT: .LBB0_2:
|
||
|
; SHORT_FORWARD-NEXT: ret
|
||
|
%c = icmp eq i32 %z, 0
|
||
|
%a = xor i32 %x, %y
|
||
|
%b = select i1 %c, i32 %a, i32 %x
|
||
|
ret i32 %b
|
||
|
}
|
||
|
|
||
|
define signext i32 @test2(i32 signext %x, i32 signext %y, i32 signext %z) {
|
||
|
; NOCMOV-LABEL: test2:
|
||
|
; NOCMOV: # %bb.0:
|
||
|
; NOCMOV-NEXT: seqz a2, a2
|
||
|
; NOCMOV-NEXT: addi a2, a2, -1
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: test2:
|
||
|
; CMOV: # %bb.0:
|
||
|
; CMOV-NEXT: xor a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB1_2
|
||
|
; CMOV-NEXT: # %bb.1:
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB1_2:
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SHORT_FORWARD-LABEL: test2:
|
||
|
; SHORT_FORWARD: # %bb.0:
|
||
|
; SHORT_FORWARD-NEXT: beqz a2, .LBB1_2
|
||
|
; SHORT_FORWARD-NEXT: # %bb.1:
|
||
|
; SHORT_FORWARD-NEXT: xor a0, a0, a1
|
||
|
; SHORT_FORWARD-NEXT: .LBB1_2:
|
||
|
; SHORT_FORWARD-NEXT: ret
|
||
|
%c = icmp eq i32 %z, 0
|
||
|
%a = xor i32 %x, %y
|
||
|
%b = select i1 %c, i32 %x, i32 %a
|
||
|
ret i32 %b
|
||
|
}
|
||
|
|
||
|
; Make sure we don't share the same basic block for two selects with the same
|
||
|
; condition.
|
||
|
define signext i32 @test3(i32 signext %v, i32 signext %w, i32 signext %x, i32 signext %y, i32 signext %z) {
|
||
|
; NOCMOV-LABEL: test3:
|
||
|
; NOCMOV: # %bb.0:
|
||
|
; NOCMOV-NEXT: seqz a4, a4
|
||
|
; NOCMOV-NEXT: addi a4, a4, -1
|
||
|
; NOCMOV-NEXT: and a1, a1, a4
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: and a3, a3, a4
|
||
|
; NOCMOV-NEXT: xor a2, a2, a3
|
||
|
; NOCMOV-NEXT: addw a0, a0, a2
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: test3:
|
||
|
; CMOV: # %bb.0:
|
||
|
; CMOV-NEXT: xor a1, a1, a0
|
||
|
; CMOV-NEXT: bnez a4, .LBB2_2
|
||
|
; CMOV-NEXT: # %bb.1:
|
||
|
; CMOV-NEXT: mv a1, a0
|
||
|
; CMOV-NEXT: .LBB2_2:
|
||
|
; CMOV-NEXT: xor a0, a2, a3
|
||
|
; CMOV-NEXT: bnez a4, .LBB2_4
|
||
|
; CMOV-NEXT: # %bb.3:
|
||
|
; CMOV-NEXT: mv a0, a2
|
||
|
; CMOV-NEXT: .LBB2_4:
|
||
|
; CMOV-NEXT: addw a0, a0, a1
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SHORT_FORWARD-LABEL: test3:
|
||
|
; SHORT_FORWARD: # %bb.0:
|
||
|
; SHORT_FORWARD-NEXT: beqz a4, .LBB2_2
|
||
|
; SHORT_FORWARD-NEXT: # %bb.1:
|
||
|
; SHORT_FORWARD-NEXT: xor a0, a0, a1
|
||
|
; SHORT_FORWARD-NEXT: .LBB2_2:
|
||
|
; SHORT_FORWARD-NEXT: beqz a4, .LBB2_4
|
||
|
; SHORT_FORWARD-NEXT: # %bb.3:
|
||
|
; SHORT_FORWARD-NEXT: xor a2, a2, a3
|
||
|
; SHORT_FORWARD-NEXT: .LBB2_4:
|
||
|
; SHORT_FORWARD-NEXT: addw a0, a0, a2
|
||
|
; SHORT_FORWARD-NEXT: ret
|
||
|
%c = icmp eq i32 %z, 0
|
||
|
%a = xor i32 %v, %w
|
||
|
%b = select i1 %c, i32 %v, i32 %a
|
||
|
%d = xor i32 %x, %y
|
||
|
%e = select i1 %c, i32 %x, i32 %d
|
||
|
%f = add i32 %b, %e
|
||
|
ret i32 %f
|
||
|
}
|
||
|
|
||
|
define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
|
||
|
; NOCMOV-LABEL: test4:
|
||
|
; NOCMOV: # %bb.0:
|
||
|
; NOCMOV-NEXT: snez a0, a2
|
||
|
; NOCMOV-NEXT: addi a0, a0, -1
|
||
|
; NOCMOV-NEXT: andi a0, a0, 3
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-NOZICOND-LABEL: test4:
|
||
|
; CMOV-NOZICOND: # %bb.0:
|
||
|
; CMOV-NOZICOND-NEXT: li a1, 0
|
||
|
; CMOV-NOZICOND-NEXT: li a0, 3
|
||
|
; CMOV-NOZICOND-NEXT: beqz a2, .LBB3_2
|
||
|
; CMOV-NOZICOND-NEXT: # %bb.1:
|
||
|
; CMOV-NOZICOND-NEXT: mv a0, a1
|
||
|
; CMOV-NOZICOND-NEXT: .LBB3_2:
|
||
|
; CMOV-NOZICOND-NEXT: ret
|
||
|
;
|
||
|
; CMOV-ZICOND-LABEL: test4:
|
||
|
; CMOV-ZICOND: # %bb.0:
|
||
|
; CMOV-ZICOND-NEXT: li a0, 3
|
||
|
; CMOV-ZICOND-NEXT: czero.nez a0, a0, a2
|
||
|
; CMOV-ZICOND-NEXT: ret
|
||
|
;
|
||
|
; SFB-NOZICOND-LABEL: test4:
|
||
|
; SFB-NOZICOND: # %bb.0:
|
||
|
; SFB-NOZICOND-NEXT: li a0, 3
|
||
|
; SFB-NOZICOND-NEXT: beqz a2, .LBB3_2
|
||
|
; SFB-NOZICOND-NEXT: # %bb.1:
|
||
|
; SFB-NOZICOND-NEXT: li a0, 0
|
||
|
; SFB-NOZICOND-NEXT: .LBB3_2:
|
||
|
; SFB-NOZICOND-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: test4:
|
||
|
; SFB-ZICOND: # %bb.0:
|
||
|
; SFB-ZICOND-NEXT: li a0, 3
|
||
|
; SFB-ZICOND-NEXT: czero.nez a0, a0, a2
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
%c = icmp eq i32 %z, 0
|
||
|
%a = select i1 %c, i32 3, i32 0
|
||
|
ret i32 %a
|
||
|
}
|
||
|
|
||
|
define i16 @select_xor_1(i16 %A, i8 %cond) {
|
||
|
; NOCMOV-LABEL: select_xor_1:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a1, a1, 63
|
||
|
; NOCMOV-NEXT: srai a1, a1, 63
|
||
|
; NOCMOV-NEXT: andi a1, a1, 43
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_xor_1:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a1, a1, 1
|
||
|
; CMOV-NEXT: xori a2, a0, 43
|
||
|
; CMOV-NEXT: beqz a1, .LBB4_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a2
|
||
|
; CMOV-NEXT: .LBB4_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SHORT_FORWARD-LABEL: select_xor_1:
|
||
|
; SHORT_FORWARD: # %bb.0: # %entry
|
||
|
; SHORT_FORWARD-NEXT: andi a1, a1, 1
|
||
|
; SHORT_FORWARD-NEXT: beqz a1, .LBB4_2
|
||
|
; SHORT_FORWARD-NEXT: # %bb.1: # %entry
|
||
|
; SHORT_FORWARD-NEXT: xori a0, a0, 43
|
||
|
; SHORT_FORWARD-NEXT: .LBB4_2: # %entry
|
||
|
; SHORT_FORWARD-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i8 %cond, 1
|
||
|
%cmp10 = icmp eq i8 %and, 0
|
||
|
%0 = xor i16 %A, 43
|
||
|
%1 = select i1 %cmp10, i16 %A, i16 %0
|
||
|
ret i16 %1
|
||
|
}
|
||
|
|
||
|
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
|
||
|
; icmp eq (and %cond, 1), 0
|
||
|
define i16 @select_xor_1b(i16 %A, i8 %cond) {
|
||
|
; NOCMOV-LABEL: select_xor_1b:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a1, a1, 63
|
||
|
; NOCMOV-NEXT: srai a1, a1, 63
|
||
|
; NOCMOV-NEXT: andi a1, a1, 43
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_xor_1b:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a1, a1, 1
|
||
|
; CMOV-NEXT: xori a2, a0, 43
|
||
|
; CMOV-NEXT: beqz a1, .LBB5_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a2
|
||
|
; CMOV-NEXT: .LBB5_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SHORT_FORWARD-LABEL: select_xor_1b:
|
||
|
; SHORT_FORWARD: # %bb.0: # %entry
|
||
|
; SHORT_FORWARD-NEXT: andi a1, a1, 1
|
||
|
; SHORT_FORWARD-NEXT: beqz a1, .LBB5_2
|
||
|
; SHORT_FORWARD-NEXT: # %bb.1: # %entry
|
||
|
; SHORT_FORWARD-NEXT: xori a0, a0, 43
|
||
|
; SHORT_FORWARD-NEXT: .LBB5_2: # %entry
|
||
|
; SHORT_FORWARD-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i8 %cond, 1
|
||
|
%cmp10 = icmp ne i8 %and, 1
|
||
|
%0 = xor i16 %A, 43
|
||
|
%1 = select i1 %cmp10, i16 %A, i16 %0
|
||
|
ret i16 %1
|
||
|
}
|
||
|
|
||
|
define i32 @select_xor_2(i32 %A, i32 %B, i8 %cond) {
|
||
|
; NOCMOV-LABEL: select_xor_2:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a2, a2, 63
|
||
|
; NOCMOV-NEXT: srai a2, a2, 63
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_xor_2:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a2, a2, 1
|
||
|
; CMOV-NEXT: xor a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB6_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB6_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: select_xor_2:
|
||
|
; SFB-ZICOND: # %bb.0: # %entry
|
||
|
; SFB-ZICOND-NEXT: andi a2, a2, 1
|
||
|
; SFB-ZICOND-NEXT: beqz a2, .LBB6_2
|
||
|
; SFB-ZICOND-NEXT: # %bb.1: # %entry
|
||
|
; SFB-ZICOND-NEXT: xor a0, a1, a0
|
||
|
; SFB-ZICOND-NEXT: .LBB6_2: # %entry
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i8 %cond, 1
|
||
|
%cmp10 = icmp eq i8 %and, 0
|
||
|
%0 = xor i32 %B, %A
|
||
|
%1 = select i1 %cmp10, i32 %A, i32 %0
|
||
|
ret i32 %1
|
||
|
}
|
||
|
|
||
|
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
|
||
|
; icmp eq (and %cond, 1), 0
|
||
|
define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
|
||
|
; NOCMOV-LABEL: select_xor_2b:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a2, a2, 63
|
||
|
; NOCMOV-NEXT: srai a2, a2, 63
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: xor a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_xor_2b:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a2, a2, 1
|
||
|
; CMOV-NEXT: xor a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB7_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB7_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: select_xor_2b:
|
||
|
; SFB-ZICOND: # %bb.0: # %entry
|
||
|
; SFB-ZICOND-NEXT: andi a2, a2, 1
|
||
|
; SFB-ZICOND-NEXT: beqz a2, .LBB7_2
|
||
|
; SFB-ZICOND-NEXT: # %bb.1: # %entry
|
||
|
; SFB-ZICOND-NEXT: xor a0, a1, a0
|
||
|
; SFB-ZICOND-NEXT: .LBB7_2: # %entry
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i8 %cond, 1
|
||
|
%cmp10 = icmp ne i8 %and, 1
|
||
|
%0 = xor i32 %B, %A
|
||
|
%1 = select i1 %cmp10, i32 %A, i32 %0
|
||
|
ret i32 %1
|
||
|
}
|
||
|
|
||
|
define i32 @select_or(i32 %A, i32 %B, i8 %cond) {
|
||
|
; NOCMOV-LABEL: select_or:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a2, a2, 63
|
||
|
; NOCMOV-NEXT: srai a2, a2, 63
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: or a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_or:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a2, a2, 1
|
||
|
; CMOV-NEXT: or a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB8_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB8_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: select_or:
|
||
|
; SFB-ZICOND: # %bb.0: # %entry
|
||
|
; SFB-ZICOND-NEXT: andi a2, a2, 1
|
||
|
; SFB-ZICOND-NEXT: beqz a2, .LBB8_2
|
||
|
; SFB-ZICOND-NEXT: # %bb.1: # %entry
|
||
|
; SFB-ZICOND-NEXT: or a0, a1, a0
|
||
|
; SFB-ZICOND-NEXT: .LBB8_2: # %entry
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i8 %cond, 1
|
||
|
%cmp10 = icmp eq i8 %and, 0
|
||
|
%0 = or i32 %B, %A
|
||
|
%1 = select i1 %cmp10, i32 %A, i32 %0
|
||
|
ret i32 %1
|
||
|
}
|
||
|
|
||
|
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
|
||
|
; icmp eq (and %cond, 1), 0
|
||
|
define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
|
||
|
; NOCMOV-LABEL: select_or_b:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a2, a2, 63
|
||
|
; NOCMOV-NEXT: srai a2, a2, 63
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: or a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_or_b:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a2, a2, 1
|
||
|
; CMOV-NEXT: or a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB9_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB9_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: select_or_b:
|
||
|
; SFB-ZICOND: # %bb.0: # %entry
|
||
|
; SFB-ZICOND-NEXT: andi a2, a2, 1
|
||
|
; SFB-ZICOND-NEXT: beqz a2, .LBB9_2
|
||
|
; SFB-ZICOND-NEXT: # %bb.1: # %entry
|
||
|
; SFB-ZICOND-NEXT: or a0, a1, a0
|
||
|
; SFB-ZICOND-NEXT: .LBB9_2: # %entry
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i8 %cond, 1
|
||
|
%cmp10 = icmp ne i8 %and, 1
|
||
|
%0 = or i32 %B, %A
|
||
|
%1 = select i1 %cmp10, i32 %A, i32 %0
|
||
|
ret i32 %1
|
||
|
}
|
||
|
|
||
|
define i32 @select_or_1(i32 %A, i32 %B, i32 %cond) {
|
||
|
; NOCMOV-LABEL: select_or_1:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a2, a2, 63
|
||
|
; NOCMOV-NEXT: srai a2, a2, 63
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: or a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_or_1:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a2, a2, 1
|
||
|
; CMOV-NEXT: or a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB10_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB10_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: select_or_1:
|
||
|
; SFB-ZICOND: # %bb.0: # %entry
|
||
|
; SFB-ZICOND-NEXT: andi a2, a2, 1
|
||
|
; SFB-ZICOND-NEXT: beqz a2, .LBB10_2
|
||
|
; SFB-ZICOND-NEXT: # %bb.1: # %entry
|
||
|
; SFB-ZICOND-NEXT: or a0, a1, a0
|
||
|
; SFB-ZICOND-NEXT: .LBB10_2: # %entry
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i32 %cond, 1
|
||
|
%cmp10 = icmp eq i32 %and, 0
|
||
|
%0 = or i32 %B, %A
|
||
|
%1 = select i1 %cmp10, i32 %A, i32 %0
|
||
|
ret i32 %1
|
||
|
}
|
||
|
|
||
|
; Equivalent to above, but with icmp ne (and %cond, 1), 1 instead of
|
||
|
; icmp eq (and %cond, 1), 0
|
||
|
define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
|
||
|
; NOCMOV-LABEL: select_or_1b:
|
||
|
; NOCMOV: # %bb.0: # %entry
|
||
|
; NOCMOV-NEXT: slli a2, a2, 63
|
||
|
; NOCMOV-NEXT: srai a2, a2, 63
|
||
|
; NOCMOV-NEXT: and a1, a1, a2
|
||
|
; NOCMOV-NEXT: or a0, a0, a1
|
||
|
; NOCMOV-NEXT: ret
|
||
|
;
|
||
|
; CMOV-LABEL: select_or_1b:
|
||
|
; CMOV: # %bb.0: # %entry
|
||
|
; CMOV-NEXT: andi a2, a2, 1
|
||
|
; CMOV-NEXT: or a1, a1, a0
|
||
|
; CMOV-NEXT: beqz a2, .LBB11_2
|
||
|
; CMOV-NEXT: # %bb.1: # %entry
|
||
|
; CMOV-NEXT: mv a0, a1
|
||
|
; CMOV-NEXT: .LBB11_2: # %entry
|
||
|
; CMOV-NEXT: ret
|
||
|
;
|
||
|
; SFB-ZICOND-LABEL: select_or_1b:
|
||
|
; SFB-ZICOND: # %bb.0: # %entry
|
||
|
; SFB-ZICOND-NEXT: andi a2, a2, 1
|
||
|
; SFB-ZICOND-NEXT: beqz a2, .LBB11_2
|
||
|
; SFB-ZICOND-NEXT: # %bb.1: # %entry
|
||
|
; SFB-ZICOND-NEXT: or a0, a1, a0
|
||
|
; SFB-ZICOND-NEXT: .LBB11_2: # %entry
|
||
|
; SFB-ZICOND-NEXT: ret
|
||
|
entry:
|
||
|
%and = and i32 %cond, 1
|
||
|
%cmp10 = icmp ne i32 %and, 1
|
||
|
%0 = or i32 %B, %A
|
||
|
%1 = select i1 %cmp10, i32 %A, i32 %0
|
||
|
ret i32 %1
|
||
|
}
|