[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