155 lines
4.6 KiB
LLVM
155 lines
4.6 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
|
|
|
|
declare i16 @llvm.ushl.sat.i16(i16, i16)
|
|
declare <2 x i16> @llvm.ushl.sat.v2i16(<2 x i16>, <2 x i16>)
|
|
|
|
; fold (shlsat undef, x) -> 0
|
|
define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shl_undef:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w0, wzr
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 undef, i16 %y)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (shlsat x, undef) -> undef
|
|
define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shl_by_undef:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 undef)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (shlsat poison, x) -> 0
|
|
define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shl_poison:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w0, wzr
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 poison, i16 %y)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (shlsat x, poison) -> undef
|
|
define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shl_by_poison:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 poison)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (shlsat x, bitwidth) -> undef
|
|
define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shl_by_bitwidth:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 16)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (ushlsat 0, x) -> 0
|
|
define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shl_zero:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w0, wzr
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 0, i16 %y)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (ushlsat x, 0) -> x
|
|
define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shlsat_by_zero:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 0)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (ushlsat c1, c2) -> c3
|
|
define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shlsat_constfold:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w0, #32
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 8, i16 2)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; fold (ushlsat c1, c2) -> sat max
|
|
define i16 @combine_shlsat_satmax(i16 %x, i16 %y) nounwind {
|
|
; CHECK-LABEL: combine_shlsat_satmax:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w0, #65535
|
|
; CHECK-NEXT: ret
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 8, i16 15)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
|
|
declare void @sink2xi16(i16, i16)
|
|
|
|
; fold (ushlsat c1, c2) -> c3 , c1/c2/c3 being vectors
|
|
define void @combine_shlsat_vector() nounwind {
|
|
; CHECK-LABEL: combine_shlsat_vector:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: mov w0, #32
|
|
; CHECK-NEXT: mov w1, #65535
|
|
; CHECK-NEXT: bl sink2xi16
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%tmp = call <2 x i16> @llvm.ushl.sat.v2i16(<2 x i16><i16 8, i16 8>,
|
|
<2 x i16><i16 2, i16 15>)
|
|
; Pass elements as arguments in a call to get CHECK statements that verify
|
|
; the constant folding.
|
|
%e0 = extractelement <2 x i16> %tmp, i16 0
|
|
%e1 = extractelement <2 x i16> %tmp, i16 1
|
|
call void @sink2xi16(i16 %e0, i16 %e1)
|
|
ret void
|
|
}
|
|
|
|
; Fold shlsat -> shl, if known not to saturate.
|
|
define i16 @combine_shlsat_to_shl(i16 %x) nounwind {
|
|
; CHECK-LABEL: combine_shlsat_to_shl:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: and w0, w0, #0xfffffffc
|
|
; CHECK-NEXT: ret
|
|
%x2 = lshr i16 %x, 2
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x2, i16 2)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; Do not fold shlsat -> shl.
|
|
define i16 @combine_shlsat_to_shl_no_fold(i16 %x) nounwind {
|
|
; CHECK-LABEL: combine_shlsat_to_shl_no_fold:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: and w8, w0, #0xfffc
|
|
; CHECK-NEXT: lsl w9, w8, #17
|
|
; CHECK-NEXT: lsl w8, w8, #14
|
|
; CHECK-NEXT: cmp w8, w9, lsr #3
|
|
; CHECK-NEXT: csinv w8, w9, wzr, eq
|
|
; CHECK-NEXT: lsr w0, w8, #16
|
|
; CHECK-NEXT: ret
|
|
%x2 = lshr i16 %x, 2
|
|
%tmp = call i16 @llvm.ushl.sat.i16(i16 %x2, i16 3)
|
|
ret i16 %tmp
|
|
}
|
|
|
|
; Fold shlsat -> shl, if known not to saturate.
|
|
define <2 x i16> @combine_shlsat_to_shl_vec(<2 x i8> %a) nounwind {
|
|
; CHECK-LABEL: combine_shlsat_to_shl_vec:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: shl v0.2s, v0.2s, #8
|
|
; CHECK-NEXT: ret
|
|
%ext = zext <2 x i8> %a to <2 x i16>
|
|
%tmp = call <2 x i16> @llvm.ushl.sat.v2i16(
|
|
<2 x i16> %ext,
|
|
<2 x i16> <i16 8, i16 8>)
|
|
ret <2 x i16> %tmp
|
|
}
|