From cc419ad7df2b90d07b7e36244cc24269be9435d8 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 12 Dec 2018 02:22:12 +0000 Subject: [PATCH] [ConstantInt] Check active bits before calling getZExtValue. Without this check, we hit an assertion in getZExtValue, if the constant value does not fit into an uint64_t. As getZExtValue returns an uint64_t, should we update getAggregateElement to take an uin64_t as well? This fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6109. Reviewers: efriedma, craig.topper, spatel Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D55547 llvm-svn: 348906 --- llvm/include/llvm/IR/Constant.h | 3 ++- llvm/lib/IR/Constants.cpp | 6 +++++- llvm/test/Transforms/SCCP/apint-bigint2.ll | 20 ++++++++++++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h index 5fdf0ea..98437f8 100644 --- a/llvm/include/llvm/IR/Constant.h +++ b/llvm/include/llvm/IR/Constant.h @@ -114,7 +114,8 @@ public: /// For aggregates (struct/array/vector) return the constant that corresponds /// to the specified element if possible, or null if not. This can return null - /// if the element index is a ConstantExpr, or if 'this' is a constant expr. + /// if the element index is a ConstantExpr, if 'this' is a constant expr or + /// if the constant does not fit into an uint64_t. Constant *getAggregateElement(unsigned Elt) const; Constant *getAggregateElement(Constant *Elt) const; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 22ffc811..df09d13 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -350,8 +350,12 @@ Constant *Constant::getAggregateElement(unsigned Elt) const { Constant *Constant::getAggregateElement(Constant *Elt) const { assert(isa(Elt->getType()) && "Index must be an integer"); - if (ConstantInt *CI = dyn_cast(Elt)) + if (ConstantInt *CI = dyn_cast(Elt)) { + // Check if the constant fits into an uint64_t. + if (CI->getValue().getActiveBits() > 64) + return nullptr; return getAggregateElement(CI->getZExtValue()); + } return nullptr; } diff --git a/llvm/test/Transforms/SCCP/apint-bigint2.ll b/llvm/test/Transforms/SCCP/apint-bigint2.ll index f28b966..20b54fed 100644 --- a/llvm/test/Transforms/SCCP/apint-bigint2.ll +++ b/llvm/test/Transforms/SCCP/apint-bigint2.ll @@ -1,11 +1,11 @@ -; RUN: opt < %s -sccp -S | not grep load +; RUN: opt < %s -sccp -S | FileCheck %s @Y = constant [6 x i101] [ i101 12, i101 123456789000000, i101 -12, i101 -123456789000000, i101 0,i101 9123456789000000] -define i101 @array() -{ -Head: +; CHECK-LABEL: @array +; CHECK-NEXT: ret i101 123456789000000 +define i101 @array() { %A = getelementptr [6 x i101], [6 x i101]* @Y, i32 0, i32 1 %B = load i101, i101* %A %D = and i101 %B, 1 @@ -16,3 +16,15 @@ Head: ret i101 %G } + +; CHECK-LABEL: @large_aggregate +; CHECK-NEXT: ret i101 undef +define i101 @large_aggregate() { + %B = load i101, i101* undef + %D = and i101 %B, 1 + %DD = or i101 %D, 1 + %F = getelementptr [6 x i101], [6 x i101]* @Y, i32 0, i32 5 + %G = getelementptr i101, i101* %F, i101 %DD + %L3 = load i101, i101* %G + ret i101 %L3 +} -- 2.7.4