From d10b731adcc8874f67d097e032b04ebc7c2e3619 Mon Sep 17 00:00:00 2001 From: DianQK Date: Tue, 10 Oct 2023 16:03:24 +0800 Subject: [PATCH] [LVI][CVP] Treat undef like a full range (#68190) When converting to ConstantRange, we should treat undef like a full range. Fixes #68381. (cherry picked from commit 81857940f278e21f7957a2833d4b6ec72819e79f) --- llvm/lib/Analysis/LazyValueInfo.cpp | 2 +- .../merge-range-and-undef.ll | 37 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 2ba6036..b66c237 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -804,7 +804,7 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange( static ConstantRange getConstantRangeOrFull(const ValueLatticeElement &Val, Type *Ty, const DataLayout &DL) { - if (Val.isConstantRange()) + if (Val.isConstantRange(/*UndefAllowed*/ false)) return Val.getConstantRange(); return ConstantRange::getFull(DL.getTypeSizeInBits(Ty)); } diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll index 2aba1f0..1d70932 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll @@ -382,3 +382,40 @@ exit: ; CVP only simplifies based on ranges for non-local conditions. call void @use(i1 %t.1) ret i64 %res } + +; Test case for PR68381. +; Because of `undef`, we can only delete the second `and` instruction. +define i32 @constant_range_and_undef_and(i1 %c0, i1 %c1, i8 %v1, i8 %v2) { +; CHECK-LABEL: @constant_range_and_undef_and( +; CHECK-NEXT: start: +; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]] +; CHECK: bb0: +; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32 +; CHECK-NEXT: br label [[BB1]] +; CHECK: bb1: +; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ] +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[V2_I32:%.*]] = zext i8 [[V2:%.*]] to i32 +; CHECK-NEXT: [[Y:%.*]] = or i32 [[X]], [[V2_I32]] +; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y]], 255 +; CHECK-NEXT: ret i32 [[Z]] +; +start: + br i1 %c0, label %bb0, label %bb1 + +bb0: + %v1_i32 = zext i8 %v1 to i32 + br label %bb1 + +bb1: + %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ] + br i1 %c1, label %bb0, label %bb2 + +bb2: + %v2_i32 = zext i8 %v2 to i32 + %y = or i32 %x, %v2_i32 + %z = and i32 %y, 255 + %z1 = and i32 %z, 255 + ret i32 %z1 +} -- 2.7.4