diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -2011,7 +2011,7 @@ } // icmp eq/ne(GV,null) -> false/true } else if (C2->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(C1)) + if (const GlobalValue *GV = dyn_cast(C1)) { // Don't try to evaluate aliases. External weak GV can be null. if (!isa(GV) && !GV->hasExternalWeakLinkage() && !NullPointerIsDefined(nullptr /* F */, @@ -2021,6 +2021,16 @@ else if (pred == ICmpInst::ICMP_NE) return ConstantInt::getTrue(C1->getContext()); } + } + + // The caller is expected to commute the operands if the constant expression + // is C2. + // C1 >= 0 --> true + if (pred == ICmpInst::ICMP_UGE) + return Constant::getAllOnesValue(ResultTy); + // C1 < 0 --> false + if (pred == ICmpInst::ICMP_ULT) + return Constant::getNullValue(ResultTy); } // If the comparison is a comparison between two i1's, simplify it. diff --git a/llvm/test/CodeGen/PowerPC/pr46923.ll b/llvm/test/CodeGen/PowerPC/pr46923.ll --- a/llvm/test/CodeGen/PowerPC/pr46923.ll +++ b/llvm/test/CodeGen/PowerPC/pr46923.ll @@ -8,7 +8,6 @@ ; CHECK-LABEL: foo: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: li r3, 0 -; CHECK-NEXT: isel r3, 0, r3, 4*cr5+lt ; CHECK-NEXT: blr entry: br label %next diff --git a/llvm/test/Transforms/InstCombine/vector_gep1-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vector_gep1-inseltpoison.ll --- a/llvm/test/Transforms/InstCombine/vector_gep1-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/vector_gep1-inseltpoison.ll @@ -64,7 +64,7 @@ define @test8() { ; CHECK-LABEL: @test8( -; CHECK-NEXT: ret icmp ult ( zext ( shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) to ), zeroinitializer) +; CHECK-NEXT: ret zeroinitializer ; %ins = insertelement poison, i32 1, i32 0 %b = shufflevector %ins, poison, zeroinitializer diff --git a/llvm/test/Transforms/InstCombine/vector_gep1.ll b/llvm/test/Transforms/InstCombine/vector_gep1.ll --- a/llvm/test/Transforms/InstCombine/vector_gep1.ll +++ b/llvm/test/Transforms/InstCombine/vector_gep1.ll @@ -64,7 +64,7 @@ define @test8() { ; CHECK-LABEL: @test8( -; CHECK-NEXT: ret icmp ult ( zext ( shufflevector ( insertelement ( undef, i32 1, i32 0), undef, zeroinitializer) to ), zeroinitializer) +; CHECK-NEXT: ret zeroinitializer ; %ins = insertelement undef, i32 1, i32 0 %b = shufflevector %ins, undef, zeroinitializer diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll b/llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll --- a/llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll @@ -3,7 +3,7 @@ define i1 @ule_null_constexpr(i8* %x) { ; CHECK-LABEL: @ule_null_constexpr( -; CHECK-NEXT: ret i1 icmp uge (i8 (...)* bitcast (i1 (i8*)* @ule_null_constexpr to i8 (...)*), i8 (...)* null) +; CHECK-NEXT: ret i1 true ; %cmp = icmp ule i8 (...)* null, bitcast (i1 (i8*)* @ule_null_constexpr to i8 (...)*) ret i1 %cmp @@ -11,7 +11,7 @@ define i1 @ugt_null_constexpr(i8* %x) { ; CHECK-LABEL: @ugt_null_constexpr( -; CHECK-NEXT: ret i1 icmp ult (i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), i8 (...)* null) +; CHECK-NEXT: ret i1 false ; %cmp = icmp ugt i8 (...)* null, bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*) ret i1 %cmp @@ -19,7 +19,7 @@ define i1 @uge_constexpr_null(i8* %x) { ; CHECK-LABEL: @uge_constexpr_null( -; CHECK-NEXT: ret i1 icmp uge (i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), i8 (...)* null) +; CHECK-NEXT: ret i1 true ; %cmp = icmp uge i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), null ret i1 %cmp @@ -27,12 +27,14 @@ define i1 @ult_constexpr_null(i8* %x) { ; CHECK-LABEL: @ult_constexpr_null( -; CHECK-NEXT: ret i1 icmp ult (i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), i8 (...)* null) +; CHECK-NEXT: ret i1 false ; %cmp = icmp ult i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), null ret i1 %cmp } +; Negative test - we don't know if the constexpr is null. + define i1 @ule_constexpr_null(i8* %x) { ; CHECK-LABEL: @ule_constexpr_null( ; CHECK-NEXT: ret i1 icmp ule (i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), i8 (...)* null) @@ -41,6 +43,8 @@ ret i1 %cmp } +; Negative test - we don't know if the constexpr is *signed* less-than null. + define i1 @slt_constexpr_null(i8* %x) { ; CHECK-LABEL: @slt_constexpr_null( ; CHECK-NEXT: ret i1 icmp slt (i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), i8 (...)* null) @@ -49,6 +53,8 @@ ret i1 %cmp } +; Negative test - we don't try to evaluate this comparison of constant expressions. + define i1 @ult_constexpr_constexpr_one(i8* %x) { ; CHECK-LABEL: @ult_constexpr_constexpr_one( ; CHECK-NEXT: ret i1 icmp ult (i8 (...)* bitcast (i1 (i8*)* @ugt_null_constexpr to i8 (...)*), i8 (...)* inttoptr (i32 1 to i8 (...)*)) diff --git a/llvm/test/Transforms/JumpThreading/thread-two-bbs.ll b/llvm/test/Transforms/JumpThreading/thread-two-bbs.ll --- a/llvm/test/Transforms/JumpThreading/thread-two-bbs.ll +++ b/llvm/test/Transforms/JumpThreading/thread-two-bbs.ll @@ -188,23 +188,24 @@ ret void } -; TODO: This is a special-case of the above pattern: +; This is a special-case of the above pattern: ; Null is guaranteed to be unsigned <= all values. define void @icmp_ule_null_constexpr(i8* %arg1, i8* %arg2) { ; CHECK-LABEL: @icmp_ule_null_constexpr( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[ARG1:%.*]], null -; CHECK-NEXT: br i1 [[CMP1]], label [[BB_BAR1:%.*]], label [[BB_END:%.*]] -; CHECK: bb_bar1: -; CHECK-NEXT: call void @bar(i32 1) -; CHECK-NEXT: br label [[BB_END]] +; CHECK-NEXT: br i1 [[CMP1]], label [[BB_END_THREAD:%.*]], label [[BB_END:%.*]] ; CHECK: bb_end: ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8* [[ARG2:%.*]], null ; CHECK-NEXT: br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]] +; CHECK: bb_end.thread: +; CHECK-NEXT: call void @bar(i32 1) +; CHECK-NEXT: [[CMP21:%.*]] = icmp ne i8* [[ARG2]], null +; CHECK-NEXT: br i1 [[CMP21]], label [[BB_EXIT:%.*]], label [[BB_BAR2]] ; CHECK: bb_bar2: ; CHECK-NEXT: call void @bar(i32 2) -; CHECK-NEXT: br label [[BB_EXIT:%.*]] +; CHECK-NEXT: br label [[BB_EXIT]] ; CHECK: bb_cont: ; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i8* [[ARG1]], inttoptr (i64 4 to i8*) ; CHECK-NEXT: br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]]