mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
implement the first part of PR8882: when lowering an inbounds
gep to explicit addressing, we know that none of the intermediate computation overflows. This could use review: it seems that the shifts certainly wouldn't overflow, but could the intermediate adds overflow if there is a negative index? Previously the testcase would instcombine to: define i1 @test(i64 %i) { %p1.idx.mask = and i64 %i, 4611686018427387903 %cmp = icmp eq i64 %p1.idx.mask, 1000 ret i1 %cmp } now we get: define i1 @test(i64 %i) { %cmp = icmp eq i64 %i, 1000 ret i1 %cmp } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125271 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
81baf14fdf
commit
6cdf2ea98e
@ -399,6 +399,10 @@ Value *InstCombiner::EmitGEPOffset(User *GEP) {
|
||||
const Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
|
||||
Value *Result = Constant::getNullValue(IntPtrTy);
|
||||
|
||||
// If the GEP is inbounds, we know that none of the addressing operations will
|
||||
// overflow in an unsigned sense.
|
||||
bool isInBounds = cast<GEPOperator>(GEP)->isInBounds();
|
||||
|
||||
// Build a mask for high order bits.
|
||||
unsigned IntPtrWidth = TD.getPointerSizeInBits();
|
||||
uint64_t PtrSizeMask = ~0ULL >> (64-IntPtrWidth);
|
||||
@ -414,31 +418,34 @@ Value *InstCombiner::EmitGEPOffset(User *GEP) {
|
||||
if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
|
||||
Size = TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
|
||||
|
||||
Result = Builder->CreateAdd(Result,
|
||||
ConstantInt::get(IntPtrTy, Size),
|
||||
GEP->getName()+".offs");
|
||||
if (Size)
|
||||
Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
|
||||
GEP->getName()+".offs",
|
||||
isInBounds /*NUW*/);
|
||||
continue;
|
||||
}
|
||||
|
||||
Constant *Scale = ConstantInt::get(IntPtrTy, Size);
|
||||
Constant *OC =
|
||||
ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
|
||||
Scale = ConstantExpr::getMul(OC, Scale);
|
||||
Scale = ConstantExpr::getMul(OC, Scale, isInBounds/*NUW*/);
|
||||
// Emit an add instruction.
|
||||
Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
|
||||
Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs",
|
||||
isInBounds /*NUW*/);
|
||||
continue;
|
||||
}
|
||||
// Convert to correct type.
|
||||
if (Op->getType() != IntPtrTy)
|
||||
Op = Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c");
|
||||
if (Size != 1) {
|
||||
Constant *Scale = ConstantInt::get(IntPtrTy, Size);
|
||||
// We'll let instcombine(mul) convert this to a shl if possible.
|
||||
Op = Builder->CreateMul(Op, Scale, GEP->getName()+".idx");
|
||||
Op = Builder->CreateMul(Op, ConstantInt::get(IntPtrTy, Size),
|
||||
GEP->getName()+".idx", isInBounds /*NUW*/);
|
||||
}
|
||||
|
||||
// Emit an add instruction.
|
||||
Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
|
||||
Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs",
|
||||
isInBounds /*NUW*/);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
target datalayout =
|
||||
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
|
||||
define i32 @test1(i32 %X) {
|
||||
entry:
|
||||
icmp slt i32 %X, 0 ; <i1>:0 [#uses=1]
|
||||
@ -218,3 +221,16 @@ define i1 @test23(i32 %x) nounwind {
|
||||
%i4 = icmp eq i32 %i3, -1
|
||||
ret i1 %i4
|
||||
}
|
||||
|
||||
@X = global [1000 x i32] zeroinitializer
|
||||
|
||||
; PR8882
|
||||
; CHECK: @test24
|
||||
; CHECK: %cmp = icmp eq i64 %i, 1000
|
||||
; CHECK: ret i1 %cmp
|
||||
define i1 @test24(i64 %i) {
|
||||
%p1 = getelementptr inbounds i32* getelementptr inbounds ([1000 x i32]* @X, i64 0, i64 0), i64 %i
|
||||
%cmp = icmp eq i32* %p1, getelementptr inbounds ([1000 x i32]* @X, i64 1, i64 0)
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ define i64 @test24b(i8* %P, i64 %A){
|
||||
%G = sub i64 %C, ptrtoint ([42 x i16]* @Arr to i64)
|
||||
ret i64 %G
|
||||
; CHECK: @test24b
|
||||
; CHECK-NEXT: shl i64 %A, 1
|
||||
; CHECK-NEXT: shl nuw i64 %A, 1
|
||||
; CHECK-NEXT: ret i64
|
||||
}
|
||||
|
||||
@ -267,7 +267,7 @@ define i64 @test25(i8* %P, i64 %A){
|
||||
%G = sub i64 %C, ptrtoint (i16* getelementptr ([42 x i16]* @Arr, i64 1, i64 0) to i64)
|
||||
ret i64 %G
|
||||
; CHECK: @test25
|
||||
; CHECK-NEXT: shl i64 %A, 1
|
||||
; CHECK-NEXT: shl nuw i64 %A, 1
|
||||
; CHECK-NEXT: add i64 {{.*}}, -84
|
||||
; CHECK-NEXT: ret i64
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user