diff options
author | Chris Lattner <sabre@nondot.org> | 2007-10-29 02:40:02 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-10-29 02:40:02 +0000 |
commit | b361ec31979b2ac40af00d5258b9571239954103 (patch) | |
tree | 2b0c96225dc3c45a170cdba2f2a2d81dae7141ba | |
parent | 3cb63ddd5183a1469e4557b3e22735ed3ace05b2 (diff) |
Fix PR1749 and InstCombine/2007-10-28-EmptyField.ll by handling
zero-length fields better.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43427 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/TargetData.cpp | 8 | ||||
-rw-r--r-- | test/Transforms/InstCombine/2007-10-28-EmptyField.ll | 24 |
2 files changed, 31 insertions, 1 deletions
diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index b2d76d8418..b1b78a8ada 100644 --- a/lib/Target/TargetData.cpp +++ b/lib/Target/TargetData.cpp @@ -83,9 +83,15 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const { assert(SI != &MemberOffsets[0] && "Offset not in structure type!"); --SI; assert(*SI <= Offset && "upper_bound didn't work"); - assert((SI == &MemberOffsets[0] || *(SI-1) < Offset) && + assert((SI == &MemberOffsets[0] || *(SI-1) <= Offset) && (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) && "Upper bound didn't work!"); + + // Multiple fields can have the same offset if any of them are zero sized. + // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop + // at the i32 element, because it is the last element at that offset. This is + // the right one to return, because anything after it will have a higher + // offset, implying that this element is non-empty. return SI-&MemberOffsets[0]; } diff --git a/test/Transforms/InstCombine/2007-10-28-EmptyField.ll b/test/Transforms/InstCombine/2007-10-28-EmptyField.ll new file mode 100644 index 0000000000..31ae985a6d --- /dev/null +++ b/test/Transforms/InstCombine/2007-10-28-EmptyField.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -instcombine -disable-output +; PR1749 + +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" +target triple = "x86_64-unknown-linux-gnu" + %struct.__large_struct = type { [100 x i64] } + %struct.compat_siginfo = type { i32, i32, i32, { [29 x i32] } } + %struct.siginfo_t = type { i32, i32, i32, { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] } } + %struct.sigval_t = type { i8* } + +define i32 @copy_siginfo_to_user32(%struct.compat_siginfo* %to, %struct.siginfo_t* %from) { +entry: + %from_addr = alloca %struct.siginfo_t* ; <%struct.siginfo_t**> [#uses=1] + %tmp344 = load %struct.siginfo_t** %from_addr, align 8 ; <%struct.siginfo_t*> [#uses=1] + %tmp345 = getelementptr %struct.siginfo_t* %tmp344, i32 0, i32 3 ; <{ { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }*> [#uses=1] + %tmp346 = getelementptr { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }* %tmp345, i32 0, i32 0 ; <{ i32, i32, [0 x i8], %struct.sigval_t, i32 }*> [#uses=1] + %tmp346347 = bitcast { i32, i32, [0 x i8], %struct.sigval_t, i32 }* %tmp346 to { i32, i32, %struct.sigval_t }* ; <{ i32, i32, %struct.sigval_t }*> [#uses=1] + %tmp348 = getelementptr { i32, i32, %struct.sigval_t }* %tmp346347, i32 0, i32 2 ; <%struct.sigval_t*> [#uses=1] + %tmp349 = getelementptr %struct.sigval_t* %tmp348, i32 0, i32 0 ; <i8**> [#uses=1] + %tmp349350 = bitcast i8** %tmp349 to i32* ; <i32*> [#uses=1] + %tmp351 = load i32* %tmp349350, align 8 ; <i32> [#uses=1] + %tmp360 = call i32 asm sideeffect "1:\09movl ${1:k},$2\0A2:\0A.section .fixup,\22ax\22\0A3:\09mov $3,$0\0A\09jmp 2b\0A.previous\0A.section __ex_table,\22a\22\0A\09.align 8\0A\09.quad 1b,3b\0A.previous", "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"( i32 %tmp351, %struct.__large_struct* null, i32 -14, i32 0 ) ; <i32> [#uses=0] + unreachable +} |