diff options
| author | Jingyue Wu <jingyue@google.com> | 2014-10-25 18:34:03 +0000 |
|---|---|---|
| committer | Jingyue Wu <jingyue@google.com> | 2014-10-25 18:34:03 +0000 |
| commit | fe72fcebf697e18af1f8cfbc7a23761045897d9b (patch) | |
| tree | 85d955abaa1b862f9c146529a3a2aa2e32883ce9 /llvm/test | |
| parent | aa139573f69cf84dd3fa6e034149e10e9c0c1c6c (diff) | |
| download | bcm5719-llvm-fe72fcebf697e18af1f8cfbc7a23761045897d9b.tar.gz bcm5719-llvm-fe72fcebf697e18af1f8cfbc7a23761045897d9b.zip | |
[SeparateConstOffsetFromGEP] Fixed a bug related to unsigned modulo
The dividend in "signed % unsigned" is treated as unsigned instead of signed,
causing unexpected behavior such as -64 % (uint64_t)24 == 0.
Added a regression test in split-gep.ll
Patched by Hao Liu.
llvm-svn: 220618
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll b/llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll index 4d07ab35b51..ea0d3f5673a 100644 --- a/llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll +++ b/llvm/test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll @@ -253,3 +253,27 @@ entry: ret float* %p ; CHECK-NEXT: ret } + +; The source code used to be buggy in checking +; (AccumulativeByteOffset % ElementTypeSizeOfGEP == 0) +; where AccumulativeByteOffset is signed but ElementTypeSizeOfGEP is unsigned. +; The compiler would promote AccumulativeByteOffset to unsigned, causing +; unexpected results. For example, while -64 % (int64_t)24 != 0, +; -64 % (uint64_t)24 == 0. +%struct3 = type { i64, i32 } +%struct2 = type { %struct3, i32 } +%struct1 = type { i64, %struct2 } +%struct0 = type { i32, i32, i64*, [100 x %struct1] } +define %struct2* @sign_mod_unsign(%struct0* %ptr, i64 %idx) { +; CHECK-LABEL: @sign_mod_unsign( +entry: + %arrayidx = add nsw i64 %idx, -2 +; CHECK-NOT: add + %ptr2 = getelementptr inbounds %struct0* %ptr, i64 0, i32 3, i64 %arrayidx, i32 1 +; CHECK: [[PTR:%[a-zA-Z0-9]+]] = getelementptr %struct0* %ptr, i64 0, i32 3, i64 %idx, i32 1 +; CHECK: [[PTR1:%[a-zA-Z0-9]+]] = bitcast %struct2* [[PTR]] to i8* +; CHECK: getelementptr i8* [[PTR1]], i64 -64 +; CHECK: bitcast + ret %struct2* %ptr2 +; CHECK-NEXT: ret +} |

