forked from OSchip/llvm-project
[InstCombine] ror/rol(X, RotAmt) == C --> X == rol/ror(C, RotAmt) (PR51567)
``` ---------------------------------------- define i1 @src(i32 %0) { %1: %2 = fshl i32 %0, i32 %0, i32 25 %3 = icmp eq i32 %2, 5 ret i1 %3 } => define i1 @tgt(i32 %0) { %1: %2 = icmp eq i32 %0, 640 ret i1 %2 } Transformation seems to be correct! ``` https://alive2.llvm.org/ce/z/GdY8Jm Solves PR51567 Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D109283
This commit is contained in:
parent
81d3ac0cf2
commit
3b5f318f5d
|
@ -3228,12 +3228,22 @@ Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
|
|||
|
||||
case Intrinsic::fshl:
|
||||
case Intrinsic::fshr:
|
||||
// (rot X, ?) == 0/-1 --> X == 0/-1
|
||||
// TODO: This transform is safe to re-use undef elts in a vector, but
|
||||
// the constant value passed in by the caller doesn't allow that.
|
||||
if (C.isNullValue() || C.isAllOnesValue())
|
||||
if (II->getArgOperand(0) == II->getArgOperand(1))
|
||||
if (II->getArgOperand(0) == II->getArgOperand(1)) {
|
||||
// (rot X, ?) == 0/-1 --> X == 0/-1
|
||||
// TODO: This transform is safe to re-use undef elts in a vector, but
|
||||
// the constant value passed in by the caller doesn't allow that.
|
||||
if (C.isNullValue() || C.isAllOnesValue())
|
||||
return new ICmpInst(Pred, II->getArgOperand(0), Cmp.getOperand(1));
|
||||
|
||||
const APInt *RotAmtC;
|
||||
// ror(X, RotAmtC) == C --> X == rol(C, RotAmtC)
|
||||
// rol(X, RotAmtC) == C --> X == ror(C, RotAmtC)
|
||||
if (match(II->getArgOperand(2), m_APInt(RotAmtC)))
|
||||
return new ICmpInst(Pred, II->getArgOperand(0),
|
||||
II->getIntrinsicID() == Intrinsic::fshl
|
||||
? ConstantInt::get(Ty, C.rotr(*RotAmtC))
|
||||
: ConstantInt::get(Ty, C.rotl(*RotAmtC)));
|
||||
}
|
||||
break;
|
||||
|
||||
case Intrinsic::uadd_sat: {
|
||||
|
|
|
@ -108,8 +108,7 @@ define <2 x i1> @ror_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) {
|
|||
|
||||
define i1 @rol_eq_cst(i8 %x) {
|
||||
; CHECK-LABEL: @rol_eq_cst(
|
||||
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 3)
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[F]], 2
|
||||
; 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)
|
||||
|
@ -119,8 +118,7 @@ define i1 @rol_eq_cst(i8 %x) {
|
|||
|
||||
define i1 @rol_ne_cst(i8 %x) {
|
||||
; CHECK-LABEL: @rol_ne_cst(
|
||||
; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 3)
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[F]], 2
|
||||
; 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)
|
||||
|
@ -132,7 +130,7 @@ 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 [[F]], 2
|
||||
; 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)
|
||||
|
@ -143,8 +141,7 @@ define i1 @rol_eq_cst_use(i8 %x) {
|
|||
|
||||
define i1 @ror_eq_cst(i8 %x) {
|
||||
; CHECK-LABEL: @ror_eq_cst(
|
||||
; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 6)
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[F]], 3
|
||||
; 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)
|
||||
|
@ -154,8 +151,7 @@ define i1 @ror_eq_cst(i8 %x) {
|
|||
|
||||
define i1 @ror_ne_cst(i8 %x) {
|
||||
; CHECK-LABEL: @ror_ne_cst(
|
||||
; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 6)
|
||||
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[F]], 3
|
||||
; 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)
|
||||
|
@ -165,8 +161,7 @@ define i1 @ror_ne_cst(i8 %x) {
|
|||
|
||||
define <2 x i1> @rol_eq_cst_vec(<2 x i5> %x) {
|
||||
; CHECK-LABEL: @rol_eq_cst_vec(
|
||||
; 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 2>
|
||||
; 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>)
|
||||
|
|
Loading…
Reference in New Issue