[llvm-bugs] [Bug 41949] New: DeadStoreElimination not handling non byte sized stores correctly (miscompile, asserts, etc)

via llvm-bugs llvm-bugs at lists.llvm.org
Mon May 20 11:37:06 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=41949

            Bug ID: 41949
           Summary: DeadStoreElimination not handling non byte sized
                    stores correctly (miscompile, asserts, etc)
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: bjorn.a.pettersson at ericsson.com
                CC: efriedma at quicinc.com, llvm-bugs at lists.llvm.org

A test case like below ends up hitting an assert 

  opt: ../llvm/include/llvm/ADT/APInt.h:1419: void
llvm::APInt::setBits(unsigned int, unsigned int): Assertion `loBit <= BitWidth
&& "loBit out of range"' failed.

in DeadStoreElimination when handling partial overwrites.


;---------------------------------------------------------------------------------
; RUN: opt < %s --data-layout "e" -dse -S | FileCheck --check-prefix CHECK-LE
%s
; RUN: opt < %s --data-layout "E" -dse -S | FileCheck --check-prefix CHECK-BE
%s

define void @test1(i32* %P) {
  %A = alloca i32
  %B = bitcast i32* %A to i28*
  %C = bitcast i32* %A to { i16, i16 }*
  %C1 = getelementptr inbounds { i16, i16 }, { i16, i16 }* %C, i32 0, i32 1
  store i28 10, i28* %B
  store i16 20, i16* %C1

  call void @test1(i32* %A)
  ret void
}
;---------------------------------------------------------------------------------


I got a feeling that DeadStoreElmination doesn't consider cases when "size in
bits" and "store size in bits" differs. opt should probably not assume anything
about the padding bits (or the internal alignment) when storing X bits using a
store size of Y bits, and Y is greater than X.


Some other problems can be observed using test2 that looks like this:

;---------------------------------------------------------------------------------
; RUN: opt < %s --data-layout "e" -dse -S | FileCheck --check-prefix CHECK-LE
%s
; RUN: opt < %s --data-layout "E" -dse -S | FileCheck --check-prefix CHECK-BE
%s

define void @test2(i32* %p) {
  %u = alloca i32
  %a = bitcast i32* %u to i32*
  %b = bitcast i32* %u to i12*
  store i32 -1, i32* %a
  store i12 20, i12* %b

  call void @test2(i32* %u)
  ret void
}
;---------------------------------------------------------------------------------

For @test2 we get a single i32 store like this for little endian
  store i32 -4076, i32* %a     ; 0xfffff014
so it does not care about that the i12 store has a 16-bit store size
Looks like bit 12-15 is taken from the first store. Or we at least have a
sitution
where opt is doing assumptions on where the padding bits are (and that it is OK
that they aren't zero).

And for big endian we get a single store like this
  store i32 22020095, i32* %a  ; 0x014fffff

which means that the memory will contain
  p+0: 0x01
  p+1: 0x4f
  p+2: 0xff
  p+3: 0xff

But normally when doing 
  store i12 20, p
I believe that we would get
  p+0: 0x00
  p+1: 0x14

So in this last case we get a miscompile.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190520/e0976008/attachment-0001.html>


More information about the llvm-bugs mailing list