From 22d22caaed861151c1a95719ccd4cff46c154b14 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 28 May 2010 15:09:00 +0000 Subject: [PATCH] Teach instcombine to promote alloca array sizes. llvm-svn: 104945 --- .../InstCombineLoadStoreAlloca.cpp | 12 +++++++++++ test/Transforms/InstCombine/alloca.ll | 20 ++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 0f2a24f59bd..fd3d5347028 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -22,6 +22,18 @@ using namespace llvm; STATISTIC(NumDeadStore, "Number of dead stores eliminated"); Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) { + // Ensure that the alloca array size argument has type intptr_t, so that + // any casting is exposed early. + if (TD) { + const Type *IntPtrTy = TD->getIntPtrType(AI.getContext()); + if (AI.getArraySize()->getType() != IntPtrTy) { + Value *V = Builder->CreateIntCast(AI.getArraySize(), + IntPtrTy, false); + AI.setOperand(0, V); + return &AI; + } + } + // Convert: alloca Ty, C - where C is a constant != 1 into: alloca [C x Ty], 1 if (AI.isArrayAllocation()) { // Check C != 1 if (const ConstantInt *C = dyn_cast(AI.getArraySize())) { diff --git a/test/Transforms/InstCombine/alloca.ll b/test/Transforms/InstCombine/alloca.ll index b9add4d7c21..e4d13673454 100644 --- a/test/Transforms/InstCombine/alloca.ll +++ b/test/Transforms/InstCombine/alloca.ll @@ -1,12 +1,13 @@ -; Zero byte allocas should be deleted. target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" -; RUN: opt < %s -instcombine -S | \ -; RUN: not grep alloca +; RUN: opt < %s -instcombine -S | FileCheck %s ; END. declare void @use(...) +; Zero byte allocas should be deleted. +; CHECK: @test +; CHECK-NOT: alloca define void @test() { %X = alloca [0 x i32] ; <[0 x i32]*> [#uses=1] call void (...)* @use( [0 x i32]* %X ) @@ -17,12 +18,18 @@ define void @test() { ret void } +; Zero byte allocas should be deleted. +; CHECK: @test2 +; CHECK-NOT: alloca define void @test2() { %A = alloca i32 ; [#uses=1] store i32 123, i32* %A ret void } +; Zero byte allocas should be deleted. +; CHECK: @test3 +; CHECK-NOT: alloca define void @test3() { %A = alloca { i32 } ; <{ i32 }*> [#uses=1] %B = getelementptr { i32 }* %A, i32 0, i32 0 ; [#uses=1] @@ -30,3 +37,10 @@ define void @test3() { ret void } +; CHECK: @test4 +; CHECK: = zext i32 %n to i64 +; CHECK: %A = alloca i32, i64 % +define i32* @test4(i32 %n) { + %A = alloca i32, i32 %n + ret i32* %A +}