| ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s |
| |
| %struct.S = type { i32, float } |
| %struct.Nested = type { %struct.S, i32 } |
| |
| @g = external global i32 |
| @arr = external global [10 x i32] |
| |
| define ptr @zero_index_local(ptr %p) { |
| ; CHECK-LABEL: @zero_index_local(ptr %p |
| ; CHECK-NEXT: ret ptr %p |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(i32) %p) |
| ret ptr %sgep |
| } |
| |
| define ptr @zero_index_global() { |
| ; CHECK-LABEL: @zero_index_global( |
| ; CHECK-NEXT: ret ptr @g |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(i32) @g) |
| ret ptr %sgep |
| } |
| |
| define ptr @zero_index_array(ptr %p) { |
| ; CHECK-LABEL: @zero_index_array(ptr %p |
| ; CHECK-NEXT: ret ptr %p |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype([10 x i32]) %p) |
| ret ptr %sgep |
| } |
| |
| define ptr addrspace(11) @zero_index_addrspace(ptr addrspace(11) %p) { |
| ; CHECK-LABEL: @zero_index_addrspace(ptr addrspace(11) %p |
| ; CHECK-NEXT: ret ptr addrspace(11) %p |
| ; |
| %sgep = call ptr addrspace(11) (ptr addrspace(11), ...) @llvm.structured.gep.p11(ptr addrspace(11) elementtype(i32) %p) |
| ret ptr addrspace(11) %sgep |
| } |
| |
| define i32 @zero_index_with_load(ptr %p) { |
| ; CHECK-LABEL: @zero_index_with_load(ptr %p |
| ; CHECK-NEXT: [[V:%.*]] = load i32, ptr %p, align 4 |
| ; CHECK-NEXT: ret i32 [[V]] |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(i32) %p) |
| %v = load i32, ptr %sgep, align 4 |
| ret i32 %v |
| } |
| |
| ; GEP with a zero index can be simplified, but SGEP cannot. |
| define ptr @zero_index_struct(ptr %p) { |
| ; CHECK-LABEL: @zero_index_struct(ptr %p |
| ; CHECK-NEXT: [[SGEP:%.*]] = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(%struct.S) %p, i32 0) |
| ; CHECK-NEXT: ret ptr [[SGEP]] |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(%struct.S) %p, i32 0) |
| ret ptr %sgep |
| } |
| |
| define ptr @one_index_struct(ptr %p) { |
| ; CHECK-LABEL: @one_index_struct(ptr %p |
| ; CHECK-NEXT: [[SGEP:%.*]] = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(%struct.S) %p, i32 1) |
| ; CHECK-NEXT: ret ptr [[SGEP]] |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(%struct.S) %p, i32 1) |
| ret ptr %sgep |
| } |
| |
| define ptr @multi_index_nested(ptr %p) { |
| ; CHECK-LABEL: @multi_index_nested( |
| ; CHECK-NEXT: [[SGEP:%.*]] = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(%struct.Nested) %p, i32 0, i32 0) |
| ; CHECK-NEXT: ret ptr [[SGEP]] |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype(%struct.Nested) %p, i32 0, i32 0) |
| ret ptr %sgep |
| } |
| |
| define ptr @dynamic_index(ptr %p, i32 %i) { |
| ; CHECK-LABEL: @dynamic_index( |
| ; CHECK-NEXT: [[SGEP:%.*]] = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype([10 x i32]) %p, i32 %i) |
| ; CHECK-NEXT: ret ptr [[SGEP]] |
| ; |
| %sgep = call ptr (ptr, ...) @llvm.structured.gep.p0(ptr elementtype([10 x i32]) %p, i32 %i) |
| ret ptr %sgep |
| } |
| |
| declare ptr @llvm.structured.gep.p0(ptr, ...) #0 |
| declare ptr addrspace(11) @llvm.structured.gep.p11(ptr addrspace(11), ...) #0 |
| |
| attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } |