diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 77ca14f88a834..a0eed31fde792 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2579,6 +2579,14 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS, continue; } + + // Propagate equalities that results from truncation with no unsigned wrap + // like (trunc nuw i64 %v to i1) == "true" or (trunc nuw i64 %v to i1) == + // "false" + if (match(LHS, m_NUWTrunc(m_Value(A)))) { + Worklist.emplace_back(A, ConstantInt::get(A->getType(), IsKnownTrue)); + continue; + } } return Changed; diff --git a/llvm/test/Transforms/GVN/trunc-nuw-equality.ll b/llvm/test/Transforms/GVN/trunc-nuw-equality.ll new file mode 100644 index 0000000000000..efe2ca3932031 --- /dev/null +++ b/llvm/test/Transforms/GVN/trunc-nuw-equality.ll @@ -0,0 +1,28 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes=gvn -S < %s | FileCheck %s + +define void @test(ptr %p, i64 %v) { +; CHECK-LABEL: define void @test( +; CHECK-SAME: ptr [[P:%.*]], i64 [[V:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TR:%.*]] = trunc nuw i64 [[V]] to i1 +; CHECK-NEXT: br i1 [[TR]], label %[[RET:.*]], label %[[STORE:.*]] +; CHECK: [[STORE]]: +; CHECK-NEXT: store i64 0, ptr [[P]], align 4 +; CHECK-NEXT: ret void +; CHECK: [[RET]]: +; CHECK-NEXT: store i64 1, ptr [[P]], align 4 +; CHECK-NEXT: ret void +; +entry: + %tr = trunc nuw i64 %v to i1 + br i1 %tr, label %ret, label %store + +store: + store i64 %v, ptr %p + ret void + +ret: + store i64 %v, ptr %p + ret void +}