From 82edf8d3297ea234698466ed7b7febb447e74ed1 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Mon, 13 Aug 2018 16:50:20 +0000 Subject: [PATCH] [InstCombine] Limit simplifyAllocaArraySize constant folding to values that fit into a uint64_t Fixes OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5223 llvm-svn: 339584 --- .../InstCombineLoadStoreAlloca.cpp | 50 ++++++++++--------- .../test/Transforms/InstCombine/alloca-big.ll | 16 ++++++ 2 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/alloca-big.ll diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 62769f077b47..5f0931ead497 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -197,30 +197,32 @@ static Instruction *simplifyAllocaArraySize(InstCombiner &IC, AllocaInst &AI) { // Convert: alloca Ty, C - where C is a constant != 1 into: alloca [C x Ty], 1 if (const ConstantInt *C = dyn_cast(AI.getArraySize())) { - Type *NewTy = ArrayType::get(AI.getAllocatedType(), C->getZExtValue()); - AllocaInst *New = IC.Builder.CreateAlloca(NewTy, nullptr, AI.getName()); - New->setAlignment(AI.getAlignment()); - - // Scan to the end of the allocation instructions, to skip over a block of - // allocas if possible...also skip interleaved debug info - // - BasicBlock::iterator It(New); - while (isa(*It) || isa(*It)) - ++It; - - // Now that I is pointing to the first non-allocation-inst in the block, - // insert our getelementptr instruction... - // - Type *IdxTy = IC.getDataLayout().getIntPtrType(AI.getType()); - Value *NullIdx = Constant::getNullValue(IdxTy); - Value *Idx[2] = {NullIdx, NullIdx}; - Instruction *GEP = - GetElementPtrInst::CreateInBounds(New, Idx, New->getName() + ".sub"); - IC.InsertNewInstBefore(GEP, *It); - - // Now make everything use the getelementptr instead of the original - // allocation. - return IC.replaceInstUsesWith(AI, GEP); + if (C->getValue().getActiveBits() <= 64) { + Type *NewTy = ArrayType::get(AI.getAllocatedType(), C->getZExtValue()); + AllocaInst *New = IC.Builder.CreateAlloca(NewTy, nullptr, AI.getName()); + New->setAlignment(AI.getAlignment()); + + // Scan to the end of the allocation instructions, to skip over a block of + // allocas if possible...also skip interleaved debug info + // + BasicBlock::iterator It(New); + while (isa(*It) || isa(*It)) + ++It; + + // Now that I is pointing to the first non-allocation-inst in the block, + // insert our getelementptr instruction... + // + Type *IdxTy = IC.getDataLayout().getIntPtrType(AI.getType()); + Value *NullIdx = Constant::getNullValue(IdxTy); + Value *Idx[2] = {NullIdx, NullIdx}; + Instruction *GEP = + GetElementPtrInst::CreateInBounds(New, Idx, New->getName() + ".sub"); + IC.InsertNewInstBefore(GEP, *It); + + // Now make everything use the getelementptr instead of the original + // allocation. + return IC.replaceInstUsesWith(AI, GEP); + } } if (isa(AI.getArraySize())) diff --git a/llvm/test/Transforms/InstCombine/alloca-big.ll b/llvm/test/Transforms/InstCombine/alloca-big.ll new file mode 100644 index 000000000000..bff5fcfe4e79 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/alloca-big.ll @@ -0,0 +1,16 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +; OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5223 +define void @test_bigalloc() { +; CHECK-LABEL: @test_bigalloc( +; CHECK-NEXT: [[TMP1:%.*]] = alloca [18446744069414584320 x i8], align 1 +; CHECK-NEXT: [[DOTSUB:%.*]] = getelementptr inbounds [18446744069414584320 x i8], [18446744069414584320 x i8]* [[TMP1]], i64 0, i64 0 +; CHECK-NEXT: store i8* [[DOTSUB]], i8** undef, align 8 +; CHECK-NEXT: ret void +; + %1 = alloca i8, i864 -4294967296 + %2 = getelementptr i8, i8* %1, i1 undef + store i8* %2, i8** undef + ret void +} -- 2.34.1