[PATCH] D38337: Check for overflows when calculating the offset in GetGEPCost.
Evgeny Astigeevich via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 4 06:05:05 PDT 2017
eastig reopened this revision.
eastig added a comment.
This revision is now accepted and ready to land.
Hi Justin,
This patch has an problem with negative offsets and 32-bit pointers.
Here is a test case:
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv7em-arm-none-eabi"
define internal void @test(i16* %pOut, i16* %pIn) {
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%pIn.pn45 = phi i16* [ %pIn, %entry ], [ %add.ptr9, %for.body ]
%i.046 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%pIn.addr.0 = getelementptr inbounds i16, i16* %pIn.pn45, i32 -32
%0 = load i16, i16* %pIn.pn45, align 2
store volatile i16 %0, i16* %pOut, align 2
%add.ptr9 = getelementptr inbounds i16, i16* %pIn.pn45, i32 -64
%inc = add nsw i32 %i.046, 1
%cmp = icmp slt i32 %inc, 21
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body
ret void
}
In armv7m the pointer size is 32-bit. "ConstIdx->getValue().sextOrTrunc(PtrSizeBits) " sets the width to 32. "BaseOffset.getLimitedValue()" calls "APInt::getZExtValue()" which returns a zero extended value. So a negative value is truncated to 32-bit and then zero extended to uint64_t. As a result a wrong value is created.
Run the following in a debugger to reproduce:
opt -loop-unswitch -S test.ll
Thanks,
Evgeny Astigeevich
Repository:
rL LLVM
https://reviews.llvm.org/D38337
More information about the llvm-commits
mailing list