; RV32IB-LABEL: sbclr_i64:
; RV32IB: # %bb.0:
; RV32IB-NEXT: andi a3, a2, 63
-; RV32IB-NEXT: addi a4, a3, -32
-; RV32IB-NEXT: addi a3, zero, 1
-; RV32IB-NEXT: bltz a4, .LBB2_2
+; RV32IB-NEXT: addi a3, a3, -32
+; RV32IB-NEXT: bltz a3, .LBB2_2
; RV32IB-NEXT: # %bb.1:
; RV32IB-NEXT: mv a2, zero
-; RV32IB-NEXT: sll a4, a3, a4
+; RV32IB-NEXT: sbset a3, zero, a3
; RV32IB-NEXT: j .LBB2_3
; RV32IB-NEXT: .LBB2_2:
-; RV32IB-NEXT: mv a4, zero
-; RV32IB-NEXT: sll a2, a3, a2
+; RV32IB-NEXT: mv a3, zero
+; RV32IB-NEXT: sbset a2, zero, a2
; RV32IB-NEXT: .LBB2_3:
; RV32IB-NEXT: andn a0, a0, a2
-; RV32IB-NEXT: andn a1, a1, a4
+; RV32IB-NEXT: andn a1, a1, a3
; RV32IB-NEXT: ret
;
; RV32IBS-LABEL: sbclr_i64:
; RV32IBS: # %bb.0:
; RV32IBS-NEXT: andi a3, a2, 63
-; RV32IBS-NEXT: addi a4, a3, -32
-; RV32IBS-NEXT: addi a3, zero, 1
-; RV32IBS-NEXT: bltz a4, .LBB2_2
+; RV32IBS-NEXT: addi a3, a3, -32
+; RV32IBS-NEXT: bltz a3, .LBB2_2
; RV32IBS-NEXT: # %bb.1:
; RV32IBS-NEXT: mv a2, zero
-; RV32IBS-NEXT: sll a4, a3, a4
+; RV32IBS-NEXT: sbset a3, zero, a3
; RV32IBS-NEXT: j .LBB2_3
; RV32IBS-NEXT: .LBB2_2:
-; RV32IBS-NEXT: mv a4, zero
-; RV32IBS-NEXT: sll a2, a3, a2
+; RV32IBS-NEXT: mv a3, zero
+; RV32IBS-NEXT: sbset a2, zero, a2
; RV32IBS-NEXT: .LBB2_3:
-; RV32IBS-NEXT: not a3, a4
+; RV32IBS-NEXT: not a3, a3
; RV32IBS-NEXT: not a2, a2
; RV32IBS-NEXT: and a0, a2, a0
; RV32IBS-NEXT: and a1, a3, a1
ret i32 %or
}
+; We can use sbsetw for 1 << x by setting the first source to zero.
+define signext i32 @sbset_i32_zero(i32 signext %a) nounwind {
+; RV32I-LABEL: sbset_i32_zero:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi a1, zero, 1
+; RV32I-NEXT: sll a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32IB-LABEL: sbset_i32_zero:
+; RV32IB: # %bb.0:
+; RV32IB-NEXT: sbset a0, zero, a0
+; RV32IB-NEXT: ret
+;
+; RV32IBS-LABEL: sbset_i32_zero:
+; RV32IBS: # %bb.0:
+; RV32IBS-NEXT: sbset a0, zero, a0
+; RV32IBS-NEXT: ret
+ %shl = shl i32 1, %a
+ ret i32 %shl
+}
+
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
; don't have yet any matching bit manipulation instructions on RV32.
; This test is presented here in case future expansions of the experimental-b
;
; RV32IB-LABEL: sbset_i64:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: addi a3, zero, 1
-; RV32IB-NEXT: sll a3, a3, a2
+; RV32IB-NEXT: sbset a3, zero, a2
; RV32IB-NEXT: srai a3, a3, 31
; RV32IB-NEXT: sbset a0, a0, a2
; RV32IB-NEXT: or a1, a3, a1
;
; RV32IBS-LABEL: sbset_i64:
; RV32IBS: # %bb.0:
-; RV32IBS-NEXT: addi a3, zero, 1
-; RV32IBS-NEXT: sll a3, a3, a2
+; RV32IBS-NEXT: sbset a3, zero, a2
; RV32IBS-NEXT: srai a3, a3, 31
; RV32IBS-NEXT: sbset a0, a0, a2
; RV32IBS-NEXT: or a1, a3, a1
ret i64 %or
}
+define signext i64 @sbset_i64_zero(i64 signext %a) nounwind {
+; RV32I-LABEL: sbset_i64_zero:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi a1, a0, -32
+; RV32I-NEXT: addi a2, zero, 1
+; RV32I-NEXT: bltz a1, .LBB7_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: mv a0, zero
+; RV32I-NEXT: sll a1, a2, a1
+; RV32I-NEXT: ret
+; RV32I-NEXT: .LBB7_2:
+; RV32I-NEXT: mv a1, zero
+; RV32I-NEXT: sll a0, a2, a0
+; RV32I-NEXT: ret
+;
+; RV32IB-LABEL: sbset_i64_zero:
+; RV32IB: # %bb.0:
+; RV32IB-NEXT: addi a1, a0, -32
+; RV32IB-NEXT: bltz a1, .LBB7_2
+; RV32IB-NEXT: # %bb.1:
+; RV32IB-NEXT: mv a0, zero
+; RV32IB-NEXT: sbset a1, zero, a1
+; RV32IB-NEXT: ret
+; RV32IB-NEXT: .LBB7_2:
+; RV32IB-NEXT: mv a1, zero
+; RV32IB-NEXT: sbset a0, zero, a0
+; RV32IB-NEXT: ret
+;
+; RV32IBS-LABEL: sbset_i64_zero:
+; RV32IBS: # %bb.0:
+; RV32IBS-NEXT: addi a1, a0, -32
+; RV32IBS-NEXT: bltz a1, .LBB7_2
+; RV32IBS-NEXT: # %bb.1:
+; RV32IBS-NEXT: mv a0, zero
+; RV32IBS-NEXT: sbset a1, zero, a1
+; RV32IBS-NEXT: ret
+; RV32IBS-NEXT: .LBB7_2:
+; RV32IBS-NEXT: mv a1, zero
+; RV32IBS-NEXT: sbset a0, zero, a0
+; RV32IBS-NEXT: ret
+ %shl = shl i64 1, %a
+ ret i64 %shl
+}
+
define i32 @sbinv_i32(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: sbinv_i32:
; RV32I: # %bb.0:
;
; RV32IB-LABEL: sbinv_i64:
; RV32IB: # %bb.0:
-; RV32IB-NEXT: addi a3, zero, 1
-; RV32IB-NEXT: sll a3, a3, a2
+; RV32IB-NEXT: sbset a3, zero, a2
; RV32IB-NEXT: srai a3, a3, 31
; RV32IB-NEXT: sbinv a0, a0, a2
; RV32IB-NEXT: xor a1, a3, a1
;
; RV32IBS-LABEL: sbinv_i64:
; RV32IBS: # %bb.0:
-; RV32IBS-NEXT: addi a3, zero, 1
-; RV32IBS-NEXT: sll a3, a3, a2
+; RV32IBS-NEXT: sbset a3, zero, a2
; RV32IBS-NEXT: srai a3, a3, 31
; RV32IBS-NEXT: sbinv a0, a0, a2
; RV32IBS-NEXT: xor a1, a3, a1
; RV32I: # %bb.0:
; RV32I-NEXT: andi a3, a2, 63
; RV32I-NEXT: addi a4, a3, -32
-; RV32I-NEXT: bltz a4, .LBB10_2
+; RV32I-NEXT: bltz a4, .LBB12_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srl a0, a1, a4
-; RV32I-NEXT: j .LBB10_3
-; RV32I-NEXT: .LBB10_2:
+; RV32I-NEXT: j .LBB12_3
+; RV32I-NEXT: .LBB12_2:
; RV32I-NEXT: srl a0, a0, a2
; RV32I-NEXT: addi a2, zero, 31
; RV32I-NEXT: sub a2, a2, a3
; RV32I-NEXT: slli a1, a1, 1
; RV32I-NEXT: sll a1, a1, a2
; RV32I-NEXT: or a0, a0, a1
-; RV32I-NEXT: .LBB10_3:
+; RV32I-NEXT: .LBB12_3:
; RV32I-NEXT: andi a0, a0, 1
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: ret
; RV32IB: # %bb.0:
; RV32IB-NEXT: andi a3, a2, 63
; RV32IB-NEXT: addi a4, a3, -32
-; RV32IB-NEXT: bltz a4, .LBB10_2
+; RV32IB-NEXT: bltz a4, .LBB12_2
; RV32IB-NEXT: # %bb.1:
; RV32IB-NEXT: srl a0, a1, a4
-; RV32IB-NEXT: j .LBB10_3
-; RV32IB-NEXT: .LBB10_2:
+; RV32IB-NEXT: j .LBB12_3
+; RV32IB-NEXT: .LBB12_2:
; RV32IB-NEXT: srl a0, a0, a2
; RV32IB-NEXT: addi a2, zero, 31
; RV32IB-NEXT: sub a2, a2, a3
; RV32IB-NEXT: slli a1, a1, 1
; RV32IB-NEXT: sll a1, a1, a2
; RV32IB-NEXT: or a0, a0, a1
-; RV32IB-NEXT: .LBB10_3:
+; RV32IB-NEXT: .LBB12_3:
; RV32IB-NEXT: andi a0, a0, 1
; RV32IB-NEXT: mv a1, zero
; RV32IB-NEXT: ret
; RV32IBS: # %bb.0:
; RV32IBS-NEXT: andi a3, a2, 63
; RV32IBS-NEXT: addi a4, a3, -32
-; RV32IBS-NEXT: bltz a4, .LBB10_2
+; RV32IBS-NEXT: bltz a4, .LBB12_2
; RV32IBS-NEXT: # %bb.1:
; RV32IBS-NEXT: srl a0, a1, a4
-; RV32IBS-NEXT: j .LBB10_3
-; RV32IBS-NEXT: .LBB10_2:
+; RV32IBS-NEXT: j .LBB12_3
+; RV32IBS-NEXT: .LBB12_2:
; RV32IBS-NEXT: srl a0, a0, a2
; RV32IBS-NEXT: addi a2, zero, 31
; RV32IBS-NEXT: sub a2, a2, a3
; RV32IBS-NEXT: slli a1, a1, 1
; RV32IBS-NEXT: sll a1, a1, a2
; RV32IBS-NEXT: or a0, a0, a1
-; RV32IBS-NEXT: .LBB10_3:
+; RV32IBS-NEXT: .LBB12_3:
; RV32IBS-NEXT: andi a0, a0, 1
; RV32IBS-NEXT: mv a1, zero
; RV32IBS-NEXT: ret