[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