aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Voung <jvoung@chromium.org>2013-06-03 14:08:49 -0700
committerJan Voung <jvoung@chromium.org>2013-06-03 14:08:49 -0700
commitb32a69792213eef2ff93440ba09c659b28733169 (patch)
treef37b0db9158fc84f52b058394415da09ce1a31f0
parent8253f255b7936070b3bae07fe9aead104f2ecde7 (diff)
PNaCl gep expansion: avoid mul by 1 for i8 arrays.
Makes the bitcode a tiny bit smaller, and avoids generating shift left by 0 code under fast-isel. BUG=https://code.google.com/p/nativeclient/issues/detail?id=3343 TEST=*.ll tests R=mseaborn@chromium.org Review URL: https://codereview.chromium.org/15861029
-rw-r--r--lib/Transforms/NaCl/ExpandGetElementPtr.cpp14
-rw-r--r--test/Transforms/NaCl/expand-getelementptr.ll14
2 files changed, 23 insertions, 5 deletions
diff --git a/lib/Transforms/NaCl/ExpandGetElementPtr.cpp b/lib/Transforms/NaCl/ExpandGetElementPtr.cpp
index 974c3193de..1fe11293ca 100644
--- a/lib/Transforms/NaCl/ExpandGetElementPtr.cpp
+++ b/lib/Transforms/NaCl/ExpandGetElementPtr.cpp
@@ -106,11 +106,15 @@ static void ExpandGEP(GetElementPtrInst *GEP, DataLayout *DL, Type *PtrType) {
} else {
FlushOffset(&Ptr, &CurrentOffset, GEP, Debug, PtrType);
Index = CastToPtrSize(Index, GEP, Debug, PtrType);
- Instruction *Mul = BinaryOperator::Create(
- Instruction::Mul, Index, ConstantInt::get(PtrType, ElementSize),
- "gep_array", GEP);
- Mul->setDebugLoc(Debug);
- Ptr = BinaryOperator::Create(Instruction::Add, Ptr, Mul, "gep", GEP);
+ if (ElementSize != 1) {
+ Index = CopyDebug(
+ BinaryOperator::Create(Instruction::Mul, Index,
+ ConstantInt::get(PtrType, ElementSize),
+ "gep_array", GEP),
+ GEP);
+ }
+ Ptr = BinaryOperator::Create(Instruction::Add, Ptr,
+ Index, "gep", GEP);
Ptr->setDebugLoc(Debug);
}
}
diff --git a/test/Transforms/NaCl/expand-getelementptr.ll b/test/Transforms/NaCl/expand-getelementptr.ll
index 2a089f2dc4..9f5a4bd8d2 100644
--- a/test/Transforms/NaCl/expand-getelementptr.ll
+++ b/test/Transforms/NaCl/expand-getelementptr.ll
@@ -4,6 +4,7 @@ target datalayout = "p:32:32:32"
%MyStruct = type { i8, i32, i8 }
%MyArray = type { [100 x i64] }
+%MyArrayOneByte = type { [100 x i8] }
; Test indexing struct field
@@ -57,6 +58,19 @@ define i64* @test_add_and_index(%MyArray* %ptr, i32 %index) {
; CHECK-NEXT: ret i64* %addr
+; Test that we don't multiply by 1 unnecessarily
+define i8* @test_add_and_index_one_byte(%MyArrayOneByte* %ptr, i32 %index) {
+ %addr = getelementptr %MyArrayOneByte* %ptr, i32 1, i32 0, i32 %index
+ ret i8* %addr
+}
+; CHECK: @test_add_and_index
+; CHECK-NEXT: %gep_int = ptrtoint %MyArrayOneByte* %ptr to i32
+; CHECK-NEXT: %gep = add i32 %gep_int, 100
+; CHECK-NEXT: %gep1 = add i32 %gep, %index
+; CHECK-NEXT: %addr = inttoptr i32 %gep1 to i8*
+; CHECK-NEXT: ret i8* %addr
+
+
; Test >32-bit array index
define i64* @test_array_index64(%MyArray* %ptr, i64 %index) {
%addr = getelementptr %MyArray* %ptr, i32 0, i32 0, i64 %index