diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4794,8 +4794,8 @@ isa(C) || isa(C)) return true; - if (C->getType()->isVectorTy()) - return !C->containsUndefElement() && !C->containsConstantExpression(); + if (C->getType()->isVectorTy() && !isa(C)) + return !C->containsConstantExpression() && !C->containsUndefElement(); } // Strip cast operations from a pointer value. diff --git a/llvm/test/Transforms/GVN/constexpr-vector-constainsundef-crash.ll b/llvm/test/Transforms/GVN/constexpr-vector-constainsundef-crash.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/GVN/constexpr-vector-constainsundef-crash.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -gvn -S %s | FileCheck %s + +; Reduced test case from +; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24278 + +; Make sure we do not crash when dealing with a vector constant expression. +define <4 x i64*> @test(i64* %ptr) { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret <4 x i64*> getelementptr (i64, i64* null, <4 x i64> ) +; +entry: + %B9 = sdiv i16 -32768, 256 + %L3 = load i64, i64* %ptr, align 4 + %B3 = sub i16 0, %B9 + %0 = insertelement <4 x i16> undef, i16 %B3, i32 3 + %1 = sub <4 x i16> zeroinitializer, %0 + %2 = sext <4 x i16> %1 to <4 x i32> + %3 = getelementptr inbounds i64, i64* null, <4 x i32> %2 + %I6 = insertelement <4 x i64*> %3, i64* undef, i64 %L3 + ret <4 x i64*> %I6 +}