236 lines
7.5 KiB
LLVM
236 lines
7.5 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
declare i8 @llvm.fshl.i8(i8, i8, i8)
|
|
declare i8 @llvm.fshr.i8(i8, i8, i8)
|
|
declare <2 x i5> @llvm.fshl.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)
|
|
declare <2 x i5> @llvm.fshr.v2i5(<2 x i5>, <2 x i5>, <2 x i5>)
|
|
declare void @use(i8)
|
|
|
|
define i1 @rol_eq(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @rol_eq(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp eq i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @rol_ne(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @rol_ne(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp ne i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ror_eq(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @ror_eq(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshr.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp eq i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
|
|
define i1 @ror_ne(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @ror_ne(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshr.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp ne i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @rol_eq_use(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @rol_eq_use(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
|
|
; CHECK-NEXT: call void @use(i8 [[F]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
|
|
call void @use(i8 %f)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp eq i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @rol_eq_uses(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @rol_eq_uses(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
|
|
; CHECK-NEXT: call void @use(i8 [[F]])
|
|
; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[Z]])
|
|
; CHECK-NEXT: call void @use(i8 [[F2]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
|
|
call void @use(i8 %f)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
|
|
call void @use(i8 %f2)
|
|
%r = icmp eq i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
define <2 x i1> @rol_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) {
|
|
; CHECK-LABEL: @rol_eq_vec(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> %z)
|
|
%f2 = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %y, <2 x i5> %y, <2 x i5> %z)
|
|
%r = icmp eq <2 x i5> %f, %f2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @ror_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) {
|
|
; CHECK-LABEL: @ror_eq_vec(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%f = tail call <2 x i5> @llvm.fshr.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> %z)
|
|
%f2 = tail call <2 x i5> @llvm.fshr.v2i5(<2 x i5> %y, <2 x i5> %y, <2 x i5> %z)
|
|
%r = icmp eq <2 x i5> %f, %f2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
|
|
define i1 @rol_eq_cst(i8 %x) {
|
|
; CHECK-LABEL: @rol_eq_cst(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 64
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
|
|
%r = icmp eq i8 %f, 2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @rol_ne_cst(i8 %x) {
|
|
; CHECK-LABEL: @rol_ne_cst(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 64
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
|
|
%r = icmp ne i8 %f, 2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @rol_eq_cst_use(i8 %x) {
|
|
; CHECK-LABEL: @rol_eq_cst_use(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 3)
|
|
; CHECK-NEXT: call void @use(i8 [[F]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], 64
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
|
|
call void @use(i8 %f)
|
|
%r = icmp eq i8 %f, 2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ror_eq_cst(i8 %x) {
|
|
; CHECK-LABEL: @ror_eq_cst(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 12
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2)
|
|
%r = icmp eq i8 %f, 3
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ror_ne_cst(i8 %x) {
|
|
; CHECK-LABEL: @ror_ne_cst(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 12
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2)
|
|
%r = icmp ne i8 %f, 3
|
|
ret i1 %r
|
|
}
|
|
|
|
define <2 x i1> @rol_eq_cst_vec(<2 x i5> %x) {
|
|
; CHECK-LABEL: @rol_eq_cst_vec(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], <i5 8, i5 8>
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> <i5 3, i5 3>)
|
|
%r = icmp eq <2 x i5> %f, <i5 2, i5 2>
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @rol_eq_cst_undef(<2 x i5> %x) {
|
|
; CHECK-LABEL: @rol_eq_cst_undef(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> <i5 3, i5 3>)
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[F]], <i5 2, i5 undef>
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> <i5 3, i5 3>)
|
|
%r = icmp eq <2 x i5> %f, <i5 2, i5 undef>
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
; negative test - not a rotate
|
|
define i1 @no_rotate(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @no_rotate(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]])
|
|
; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y]], i8 [[Y]], i8 [[Z]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[F]], [[F2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp eq i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
; negative test - wrong predicate
|
|
define i1 @wrong_pred(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @wrong_pred(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
|
|
; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[Z]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[F]], [[F2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z)
|
|
%r = icmp ult i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
; negative test - rotate amounts mismatch
|
|
define i1 @amounts_mismatch(i8 %x, i8 %y, i8 %z, i8 %w) {
|
|
; CHECK-LABEL: @amounts_mismatch(
|
|
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]])
|
|
; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[W:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[F]], [[F2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z)
|
|
%f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %w)
|
|
%r = icmp eq i8 %f, %f2
|
|
ret i1 %r
|
|
}
|
|
|
|
; negative test - wrong predicate
|
|
define i1 @wrong_pred2(i8 %x) {
|
|
; CHECK-LABEL: @wrong_pred2(
|
|
; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 5)
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[F]], 2
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 27)
|
|
%r = icmp ugt i8 %f, 2
|
|
ret i1 %r
|
|
}
|