From ed2232502eac83d649c61c3f9bbfbd642b864319 Mon Sep 17 00:00:00 2001 From: Wojciech Matyjewicz Date: Wed, 12 Dec 2007 15:21:32 +0000 Subject: [PATCH] 1. "Upgrage" comments. 2. Using zero-extended value of Scale and unsigned division is safe provided that Scale doesn't have the sign bit set. Previously these 2 instructions: %p = bitcast [100 x {i8,i8,i8}]* %x to i8* %q = getelementptr i8* %p, i32 -4 were combined into: %q = getelementptr [100 x { i8, i8, i8 }]* %x, i32 0, i32 1431655764, i32 0 what was incorrect. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44936 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 31 ++++++++++--------- .../InstCombine/2007-12-12-GEPScale.ll | 10 ++++++ 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 test/Transforms/InstCombine/2007-12-12-GEPScale.ll diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index a868e56ca63..653d35e34f4 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -8879,8 +8879,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { if (!isa(X->getType())) { // Not interesting. Source pointer must be a cast from pointer. } else if (HasZeroPointerIndex) { - // transform: GEP (cast [10 x ubyte]* X to [0 x ubyte]*), long 0, ... - // into : GEP [10 x ubyte]* X, long 0, ... + // transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... + // into : GEP [10 x i8]* X, i32 0, ... // // This occurs when the program declares an array extern like "int X[];" // @@ -8900,8 +8900,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { } } else if (GEP.getNumOperands() == 2) { // Transform things like: - // %t = getelementptr ubyte* cast ([2 x int]* %str to uint*), uint %V - // into: %t1 = getelementptr [2 x int*]* %str, int 0, uint %V; cast + // %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V + // into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast const Type *SrcElTy = cast(X->getType())->getElementType(); const Type *ResElTy=cast(PtrOp->getType())->getElementType(); if (isa(SrcElTy) && @@ -8917,12 +8917,11 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { } // Transform things like: - // getelementptr sbyte* cast ([100 x double]* X to sbyte*), int %tmp + // getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp // (where tmp = 8*tmp2) into: - // getelementptr [100 x double]* %arr, int 0, int %tmp.2 + // getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast - if (isa(SrcElTy) && - (ResElTy == Type::Int8Ty || ResElTy == Type::Int8Ty)) { + if (isa(SrcElTy) && ResElTy == Type::Int8Ty) { uint64_t ArrayEltSize = TD->getABITypeSize(cast(SrcElTy)->getElementType()); @@ -8949,16 +8948,18 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { NewIdx = Inst->getOperand(0); } } - + // If the index will be to exactly the right offset with the scale taken - // out, perform the transformation. - if (Scale && Scale->getZExtValue() % ArrayEltSize == 0) { - if (isa(Scale)) - Scale = ConstantInt::get(Scale->getType(), - Scale->getZExtValue() / ArrayEltSize); + // out, perform the transformation. Note, we don't know whether Scale is + // signed or not. We'll use unsigned version of division/modulo + // operation after making sure Scale doesn't have the sign bit set. + if (Scale && Scale->getSExtValue() >= 0LL && + Scale->getZExtValue() % ArrayEltSize == 0) { + Scale = ConstantInt::get(Scale->getType(), + Scale->getZExtValue() / ArrayEltSize); if (Scale->getZExtValue() != 1) { Constant *C = ConstantExpr::getIntegerCast(Scale, NewIdx->getType(), - true /*SExt*/); + false /*ZExt*/); Instruction *Sc = BinaryOperator::createMul(NewIdx, C, "idxscale"); NewIdx = InsertNewInstBefore(Sc, GEP); } diff --git a/test/Transforms/InstCombine/2007-12-12-GEPScale.ll b/test/Transforms/InstCombine/2007-12-12-GEPScale.ll new file mode 100644 index 00000000000..6580f90411a --- /dev/null +++ b/test/Transforms/InstCombine/2007-12-12-GEPScale.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 1431655764 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" + +define i8* @foo([100 x {i8,i8,i8}]* %x) { +entry: + %p = bitcast [100 x {i8,i8,i8}]* %x to i8* + %q = getelementptr i8* %p, i32 -4 + ret i8* %q +}