diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3404,6 +3404,15 @@ MaxRecurse-1)) return V; } + // Fold (zext X) ule (sext X), (zext X) sge (sext X) to true. + else if (SExtInst *RI = dyn_cast(RHS)) { + if (SrcOp == RI->getOperand(0)) { + if (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_SGE) + return ConstantInt::getTrue(ITy); + if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SLT) + return ConstantInt::getFalse(ITy); + } + } // Turn icmp (zext X), Cst into a compare of X and Cst if Cst is extended // too. If not, then try to deduce the result of the comparison. else if (ConstantInt *CI = dyn_cast(RHS)) { @@ -3463,6 +3472,15 @@ Q, MaxRecurse-1)) return V; } + // Fold (sext X) uge (zext X), (sext X) sle (zext X) to true. + else if (ZExtInst *RI = dyn_cast(RHS)) { + if (SrcOp == RI->getOperand(0)) { + if (Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_SLE) + return ConstantInt::getTrue(ITy); + if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SGT) + return ConstantInt::getFalse(ITy); + } + } // Turn icmp (sext X), Cst into a compare of X and Cst if Cst is extended // too. If not, then try to deduce the result of the comparison. else if (ConstantInt *CI = dyn_cast(RHS)) { diff --git a/llvm/test/Transforms/InstSimplify/cmp_ext.ll b/llvm/test/Transforms/InstSimplify/cmp_ext.ll --- a/llvm/test/Transforms/InstSimplify/cmp_ext.ll +++ b/llvm/test/Transforms/InstSimplify/cmp_ext.ll @@ -16,10 +16,7 @@ define i1 @zext_ugt_sext(i32 %x) { ; CHECK-LABEL: @zext_ugt_sext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[ZEXT]], [[SEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -42,10 +39,7 @@ define i1 @zext_ule_sext(i32 %x) { ; CHECK-LABEL: @zext_ule_sext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[ZEXT]], [[SEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -55,10 +49,7 @@ define i1 @zext_sge_sext(i32 %x) { ; CHECK-LABEL: @zext_sge_sext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[ZEXT]], [[SEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -81,10 +72,7 @@ define i1 @zext_slt_sext(i32 %x) { ; CHECK-LABEL: @zext_slt_sext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[ZEXT]], [[SEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -107,10 +95,7 @@ define i1 @sext_uge_zext(i32 %x) { ; CHECK-LABEL: @sext_uge_zext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[SEXT]], [[ZEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -133,10 +118,7 @@ define i1 @sext_ult_zext(i32 %x) { ; CHECK-LABEL: @sext_ult_zext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[SEXT]], [[ZEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -172,10 +154,7 @@ define i1 @sext_sgt_zext(i32 %x) { ; CHECK-LABEL: @sext_sgt_zext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[SEXT]], [[ZEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -198,10 +177,7 @@ define i1 @sext_sle_zext(i32 %x) { ; CHECK-LABEL: @sext_sle_zext( -; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[X:%.*]] to i64 -; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X]] to i64 -; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[SEXT]], [[ZEXT]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %sext = sext i32 %x to i64 %zext = zext i32 %x to i64 @@ -211,10 +187,7 @@ define <4 x i1> @zext_ugt_sext_vec(<4 x i32> %x) { ; CHECK-LABEL: @zext_ugt_sext_vec( -; CHECK-NEXT: [[SEXT:%.*]] = sext <4 x i32> [[X:%.*]] to <4 x i64> -; CHECK-NEXT: [[ZEXT:%.*]] = zext <4 x i32> [[X]] to <4 x i64> -; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <4 x i64> [[ZEXT]], [[SEXT]] -; CHECK-NEXT: ret <4 x i1> [[CMP]] +; CHECK-NEXT: ret <4 x i1> zeroinitializer ; %sext = sext <4 x i32> %x to <4 x i64> %zext = zext <4 x i32> %x to <4 x i64> @@ -224,10 +197,7 @@ define <4 x i1> @sext_ult_zext_vec(<4 x i32> %x) { ; CHECK-LABEL: @sext_ult_zext_vec( -; CHECK-NEXT: [[SEXT:%.*]] = sext <4 x i32> [[X:%.*]] to <4 x i64> -; CHECK-NEXT: [[ZEXT:%.*]] = zext <4 x i32> [[X]] to <4 x i64> -; CHECK-NEXT: [[CMP:%.*]] = icmp ult <4 x i64> [[SEXT]], [[ZEXT]] -; CHECK-NEXT: ret <4 x i1> [[CMP]] +; CHECK-NEXT: ret <4 x i1> zeroinitializer ; %sext = sext <4 x i32> %x to <4 x i64> %zext = zext <4 x i32> %x to <4 x i64>