Files
TheRock/compiler/amd-llvm/llvm/test/tools/llubi/gep.ll
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

147 lines
11 KiB
LLVM
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
target datalayout = "e-p:64:64:64:32"
%struct = type { i64, [2 x i32], i64 }
define ptr @dead_stack_object() {
%alloc = alloca i32
ret ptr %alloc
}
define void @main() {
%alloc = alloca i32
%alloc_struct = alloca %struct
%gep = getelementptr i8, ptr %alloc, i64 3
%gep_poison_base = getelementptr i8, ptr poison, i64 1
%gep_poison_idx = getelementptr i8, ptr %alloc, i64 poison
; The indices are first converted to offsets in the pointer’s index type.
; The index itself is sign-extended or truncated, and then multiplied by the type allocation size
%gep_trunc_idx = getelementptr i32, ptr %alloc, i128 18446744073709551616
%gep_sext_idx = getelementptr i32, ptr %alloc, i8 -1
; The offsets are then added to the low bits of the base address up to the index type width,
; with silently-wrapping two’s complement arithmetic.
%large_address = inttoptr i64 -1 to ptr
%gep_update_idx_bits = getelementptr i32, ptr %large_address, i64 1
%gep_struct = getelementptr %struct, ptr %alloc_struct, i64 0, i32 1, i32 1
%gep_scalable_vec = getelementptr <vscale x 4 x i32>, ptr null, i64 4
%gep_vec_idx = getelementptr [2 x i32], ptr %alloc, i64 1, <2 x i64> <i64 0, i64 2>
%ptr_vec_insert = insertelement <2 x ptr> poison, ptr %alloc, i32 0
%ptr_vec_splat = shufflevector <2 x ptr> %ptr_vec_insert, <2 x ptr> poison, <2 x i32> zeroinitializer
%gep_vec_ptr = getelementptr i32, <2 x ptr> %ptr_vec_splat, i64 1
%gep_vec_ptr_vec_idx = getelementptr i32, <2 x ptr> %ptr_vec_splat, <2 x i64> <i64 0, i64 2>
; Note that getelementptr with all-zero indices is always considered to be inbounds, even if the base
; pointer does not point to an allocated object. As a corollary, the only pointer in bounds of the null
; pointer in the default address space is the null pointer itself.
%gep_inbounds_valid_null = getelementptr inbounds i8, ptr null, i64 0
%gep_inbounds_invalid_null = getelementptr inbounds i8, ptr null, i64 1
; The base pointer has an in bounds address of the allocated object that it is based on.
; This means that it points into that allocated object, or to its end.
%gep_inbounds_valid1 = getelementptr inbounds i8, ptr %alloc, i64 3
%gep_inbounds_valid2 = getelementptr inbounds i8, ptr %alloc, i64 4
%gep_inbounds_invalid1 = getelementptr inbounds i8, ptr %alloc, i64 -1
%gep_inbounds_invalid2 = getelementptr inbounds i8, ptr %alloc, i64 5
; During the successive addition of offsets to the address, the resulting pointer
; must remain in bounds of the allocated object at each step.
%gep_inbounds_invalid3 = getelementptr inbounds %struct, ptr %alloc_struct, i64 1, i32 1, i32 -2
%dead_stack_ptr = call ptr @dead_stack_object()
; The object does not have to be live anymore; being in-bounds of a deallocated object is sufficient.
%gep_inbounds_valid4 = getelementptr inbounds i8, ptr %dead_stack_ptr, i64 4
%gep_inbounds_invalid4 = getelementptr inbounds i8, ptr %dead_stack_ptr, i64 5
; If the type of an index is larger than the pointer index type, the truncation to the pointer index
; type preserves the signed value (trunc nsw).
%gep_nusw_valid1 = getelementptr nusw i8, ptr %alloc, i64 -1
%gep_nusw_invalid1 = getelementptr nusw i8, ptr %large_address, i64 -2147483649
; The multiplication of an index by the type size does not wrap the pointer index type in a signed sense (mul nsw).
%gep_nusw_valid2 = getelementptr nusw i32, ptr null, i32 536870911
%gep_nusw_invalid2 = getelementptr nusw i32, ptr null, i32 536870912
; The successive addition of each offset (without adding the base address) does not wrap the pointer
; index type in a signed sense (add nsw).
%gep_nusw_valid3 = getelementptr nusw [2 x i16], ptr null, i32 536870911, i32 1
%gep_nusw_invalid3 = getelementptr nusw [2 x i16], ptr null, i32 536870911, i32 2
; The successive addition of the current address, truncated to the pointer index type and interpreted as an unsigned
; number, and each offset, interpreted as a signed number, does not wrap the pointer index type.
%large_address2 = inttoptr i64 -4 to ptr
%gep_nusw_valid4 = getelementptr nusw i8, ptr %large_address2, i64 3
%gep_nusw_invalid4 = getelementptr nusw i8, ptr %large_address2, i64 4
%gep_nusw_valid5 = getelementptr nusw i8, ptr %large_address2, i64 -4
%gep_nusw_invalid5 = getelementptr nusw i8, ptr %alloc, i64 -16
; If the type of an index is larger than the pointer index type,
; the truncation to the pointer index type preserves the unsigned value (trunc nuw).
%gep_nuw_valid1 = getelementptr nuw i8, ptr null, i64 2147483647
%gep_nuw_invalid1 = getelementptr nuw i8, ptr null, i64 -1
; The multiplication of an index by the type size does not wrap
; the pointer index type in an unsigned sense (mul nuw).
%gep_nuw_valid2 = getelementptr nuw i32, ptr null, i32 1073741823
%gep_nuw_invalid2 = getelementptr nuw i32, ptr null, i32 1073741824
; The successive addition of each offset (without adding the base address) does not
; wrap the pointer index type in an unsigned sense (add nuw).
%gep_nuw_valid3 = getelementptr nuw [2 x i16], ptr null, i32 1073741823, i32 1
%gep_nuw_invalid3 = getelementptr nuw [2 x i16], ptr null, i32 1073741823, i32 2
; The successive addition of the current address, truncated to the pointer index type and interpreted
; as an unsigned number, and each offset, also interpreted as an unsigned number, does not wrap the
; pointer index type (add nuw).
%gep_nuw_valid4 = getelementptr nuw i32, ptr %alloc, i64 1073741821
%gep_nuw_invalid4 = getelementptr nuw i32, ptr %alloc, i64 1073741822
ret void
}
; CHECK: Entering function: main
; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
; CHECK-NEXT: %alloc_struct = alloca %struct, align 8 => ptr 0x10 [alloc_struct]
; CHECK-NEXT: %gep = getelementptr i8, ptr %alloc, i64 3 => ptr 0xB [alloc + 3]
; CHECK-NEXT: %gep_poison_base = getelementptr i8, ptr poison, i64 1 => poison
; CHECK-NEXT: %gep_poison_idx = getelementptr i8, ptr %alloc, i64 poison => poison
; CHECK-NEXT: %gep_trunc_idx = getelementptr i32, ptr %alloc, i128 18446744073709551616 => ptr 0x8 [alloc]
; CHECK-NEXT: %gep_sext_idx = getelementptr i32, ptr %alloc, i8 -1 => ptr 0x4 [alloc + -4]
; CHECK-NEXT: %large_address = inttoptr i64 -1 to ptr => ptr 0xFFFFFFFFFFFFFFFF [nullary]
; CHECK-NEXT: %gep_update_idx_bits = getelementptr i32, ptr %large_address, i64 1 => ptr 0xFFFFFFFF00000003 [nullary]
; CHECK-NEXT: %gep_struct = getelementptr %struct, ptr %alloc_struct, i64 0, i32 1, i32 1 => ptr 0x1C [alloc_struct + 12]
; CHECK-NEXT: %gep_scalable_vec = getelementptr <vscale x 4 x i32>, ptr null, i64 4 => ptr 0x100 [nullary]
; CHECK-NEXT: %gep_vec_idx = getelementptr [2 x i32], ptr %alloc, i64 1, <2 x i64> <i64 0, i64 2> => { ptr 0x10 [alloc + 8], ptr 0x18 [alloc + 16] }
; CHECK-NEXT: %ptr_vec_insert = insertelement <2 x ptr> poison, ptr %alloc, i32 0 => { ptr 0x8 [alloc], poison }
; CHECK-NEXT: %ptr_vec_splat = shufflevector <2 x ptr> %ptr_vec_insert, <2 x ptr> poison, <2 x i32> zeroinitializer => { ptr 0x8 [alloc], ptr 0x8 [alloc] }
; CHECK-NEXT: %gep_vec_ptr = getelementptr i32, <2 x ptr> %ptr_vec_splat, i64 1 => { ptr 0xC [alloc + 4], ptr 0xC [alloc + 4] }
; CHECK-NEXT: %gep_vec_ptr_vec_idx = getelementptr i32, <2 x ptr> %ptr_vec_splat, <2 x i64> <i64 0, i64 2> => { ptr 0x8 [alloc], ptr 0x10 [alloc + 8] }
; CHECK-NEXT: %gep_inbounds_valid_null = getelementptr inbounds i8, ptr null, i64 0 => ptr 0x0 [nullary]
; CHECK-NEXT: %gep_inbounds_invalid_null = getelementptr inbounds i8, ptr null, i64 1 => poison
; CHECK-NEXT: %gep_inbounds_valid1 = getelementptr inbounds i8, ptr %alloc, i64 3 => ptr 0xB [alloc + 3]
; CHECK-NEXT: %gep_inbounds_valid2 = getelementptr inbounds i8, ptr %alloc, i64 4 => ptr 0xC [alloc + 4]
; CHECK-NEXT: %gep_inbounds_invalid1 = getelementptr inbounds i8, ptr %alloc, i64 -1 => poison
; CHECK-NEXT: %gep_inbounds_invalid2 = getelementptr inbounds i8, ptr %alloc, i64 5 => poison
; CHECK-NEXT: %gep_inbounds_invalid3 = getelementptr inbounds %struct, ptr %alloc_struct, i64 1, i32 1, i32 -2 => poison
; CHECK-NEXT: Entering function: dead_stack_object
; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x28 [alloc]
; CHECK-NEXT: ret ptr %alloc
; CHECK-NEXT: Exiting function: dead_stack_object
; CHECK-NEXT: %dead_stack_ptr = call ptr @dead_stack_object() => ptr 0x28 [alloc (dangling)]
; CHECK-NEXT: %gep_inbounds_valid4 = getelementptr inbounds i8, ptr %dead_stack_ptr, i64 4 => ptr 0x2C [alloc + 4 (dangling)]
; CHECK-NEXT: %gep_inbounds_invalid4 = getelementptr inbounds i8, ptr %dead_stack_ptr, i64 5 => poison
; CHECK-NEXT: %gep_nusw_valid1 = getelementptr nusw i8, ptr %alloc, i64 -1 => ptr 0x7 [alloc + -1]
; CHECK-NEXT: %gep_nusw_invalid1 = getelementptr nusw i8, ptr %large_address, i64 -2147483649 => poison
; CHECK-NEXT: %gep_nusw_valid2 = getelementptr nusw i32, ptr null, i32 536870911 => ptr 0x7FFFFFFC [nullary]
; CHECK-NEXT: %gep_nusw_invalid2 = getelementptr nusw i32, ptr null, i32 536870912 => poison
; CHECK-NEXT: %gep_nusw_valid3 = getelementptr nusw [2 x i16], ptr null, i32 536870911, i32 1 => ptr 0x7FFFFFFE [nullary]
; CHECK-NEXT: %gep_nusw_invalid3 = getelementptr nusw [2 x i16], ptr null, i32 536870911, i32 2 => poison
; CHECK-NEXT: %large_address2 = inttoptr i64 -4 to ptr => ptr 0xFFFFFFFFFFFFFFFC [nullary]
; CHECK-NEXT: %gep_nusw_valid4 = getelementptr nusw i8, ptr %large_address2, i64 3 => ptr 0xFFFFFFFFFFFFFFFF [nullary]
; CHECK-NEXT: %gep_nusw_invalid4 = getelementptr nusw i8, ptr %large_address2, i64 4 => poison
; CHECK-NEXT: %gep_nusw_valid5 = getelementptr nusw i8, ptr %large_address2, i64 -4 => ptr 0xFFFFFFFFFFFFFFF8 [nullary]
; CHECK-NEXT: %gep_nusw_invalid5 = getelementptr nusw i8, ptr %alloc, i64 -16 => poison
; CHECK-NEXT: %gep_nuw_valid1 = getelementptr nuw i8, ptr null, i64 2147483647 => ptr 0x7FFFFFFF [nullary]
; CHECK-NEXT: %gep_nuw_invalid1 = getelementptr nuw i8, ptr null, i64 -1 => poison
; CHECK-NEXT: %gep_nuw_valid2 = getelementptr nuw i32, ptr null, i32 1073741823 => ptr 0xFFFFFFFC [nullary]
; CHECK-NEXT: %gep_nuw_invalid2 = getelementptr nuw i32, ptr null, i32 1073741824 => poison
; CHECK-NEXT: %gep_nuw_valid3 = getelementptr nuw [2 x i16], ptr null, i32 1073741823, i32 1 => ptr 0xFFFFFFFE [nullary]
; CHECK-NEXT: %gep_nuw_invalid3 = getelementptr nuw [2 x i16], ptr null, i32 1073741823, i32 2 => poison
; CHECK-NEXT: %gep_nuw_valid4 = getelementptr nuw i32, ptr %alloc, i64 1073741821 => ptr 0xFFFFFFFC [alloc + 4294967284]
; CHECK-NEXT: %gep_nuw_invalid4 = getelementptr nuw i32, ptr %alloc, i64 1073741822 => poison
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main