; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s ;; Check that we do not create new inttoptr instructions for unstable pointers ;; or pointers with external state (even if the values are all constants). ;; NOTE: for all but the zero address space, the GEP should only modify the ;; low 8 bits of the pointer. target datalayout = "p:16:16:16:16-p1:16:16:16:8-pu2:16:16:16:8-pe3:16:16:16:8" define ptr @test_null_base_normal() { ; CHECK-LABEL: define ptr @test_null_base_normal() { ; CHECK-NEXT: ret ptr inttoptr (i16 -2 to ptr) ; %gep = getelementptr i8, ptr null, i8 -2 ret ptr %gep } define ptr @test_inttoptr_base_normal() { ; CHECK-LABEL: define ptr @test_inttoptr_base_normal() { ; CHECK-NEXT: ret ptr null ; %base = inttoptr i16 -1 to ptr %gep = getelementptr i8, ptr %base, i8 1 ret ptr %gep } ;; Transformation is fine for non-integral address space, but we can only change ;; the index bits: (i8 -2 == i16 254) define ptr addrspace(1) @test_null_base_nonintegral() { ; CHECK-LABEL: define ptr addrspace(1) @test_null_base_nonintegral() { ; CHECK-NEXT: ret ptr addrspace(1) inttoptr (i16 254 to ptr addrspace(1)) ; %gep = getelementptr i8, ptr addrspace(1) null, i8 -2 ret ptr addrspace(1) %gep } define ptr addrspace(1) @test_inttoptr_base_nonintegral() { ; CHECK-LABEL: define ptr addrspace(1) @test_inttoptr_base_nonintegral() { ; CHECK-NEXT: ret ptr addrspace(1) inttoptr (i16 -256 to ptr addrspace(1)) ; %base = inttoptr i16 -1 to ptr addrspace(1) %gep = getelementptr i8, ptr addrspace(1) %base, i8 1 ret ptr addrspace(1) %gep } ;; For unstable pointers we should avoid any introduction of inttoptr define ptr addrspace(2) @test_null_base_unstable() { ; CHECK-LABEL: define ptr addrspace(2) @test_null_base_unstable() { ; CHECK-NEXT: ret ptr addrspace(2) getelementptr (i8, ptr addrspace(2) null, i8 -2) ; %gep = getelementptr i8, ptr addrspace(2) null, i8 -2 ret ptr addrspace(2) %gep } define ptr addrspace(2) @test_inttoptr_base_unstable() { ; CHECK-LABEL: define ptr addrspace(2) @test_inttoptr_base_unstable() { ; CHECK-NEXT: ret ptr addrspace(2) getelementptr (i8, ptr addrspace(2) inttoptr (i16 -1 to ptr addrspace(2)), i8 1) ; %base = inttoptr i16 -1 to ptr addrspace(2) %gep = getelementptr i8, ptr addrspace(2) %base, i8 1 ret ptr addrspace(2) %gep } ;; The same is true for pointers with external state: no new inttoptr define ptr addrspace(3) @test_null_base_external() { ; CHECK-LABEL: define ptr addrspace(3) @test_null_base_external() { ; CHECK-NEXT: ret ptr addrspace(3) getelementptr (i8, ptr addrspace(3) null, i8 -2) ; %gep = getelementptr i8, ptr addrspace(3) null, i8 -2 ret ptr addrspace(3) %gep } define ptr addrspace(3) @test_inttoptr_base_external() { ; CHECK-LABEL: define ptr addrspace(3) @test_inttoptr_base_external() { ; CHECK-NEXT: ret ptr addrspace(3) getelementptr (i8, ptr addrspace(3) inttoptr (i16 -1 to ptr addrspace(3)), i8 1) ; %base = inttoptr i16 -1 to ptr addrspace(3) %gep = getelementptr i8, ptr addrspace(3) %base, i8 1 ret ptr addrspace(3) %gep } define <2 x ptr> @test_vec_null_base_normal() { ; CHECK-LABEL: define <2 x ptr> @test_vec_null_base_normal() { ; CHECK-NEXT: ret <2 x ptr> getelementptr (i8, <2 x ptr> splat (ptr null), <2 x i16> ) ; %gep = getelementptr i8, <2 x ptr> , <2 x i8> ret <2 x ptr> %gep } define <2 x ptr> @test_vec_inttoptr_base_normal() { ; CHECK-LABEL: define <2 x ptr> @test_vec_inttoptr_base_normal() { ; CHECK-NEXT: ret <2 x ptr> getelementptr (i8, <2 x ptr> , <2 x i16> ) ; %base = inttoptr <2 x i16> to <2 x ptr> %gep = getelementptr i8, <2 x ptr> %base, <2 x i8> ret <2 x ptr> %gep } ;; Transformation is fine for non-integral address space, but we can only change ;; the index bits: (i8 -2 == i16 254) define <2 x ptr addrspace(1)> @test_vec_null_base_nonintegral() { ; CHECK-LABEL: define <2 x ptr addrspace(1)> @test_vec_null_base_nonintegral() { ; CHECK-NEXT: ret <2 x ptr addrspace(1)> getelementptr (i8, <2 x ptr addrspace(1)> splat (ptr addrspace(1) null), <2 x i8> ) ; %gep = getelementptr i8, <2 x ptr addrspace(1)> , <2 x i8> ret <2 x ptr addrspace(1)> %gep } define <2 x ptr addrspace(1)> @test_vec_inttoptr_base_nonintegral() { ; CHECK-LABEL: define <2 x ptr addrspace(1)> @test_vec_inttoptr_base_nonintegral() { ; CHECK-NEXT: ret <2 x ptr addrspace(1)> getelementptr (i8, <2 x ptr addrspace(1)> , <2 x i8> ) ; %base = inttoptr <2 x i16> to <2 x ptr addrspace(1)> %gep = getelementptr i8, <2 x ptr addrspace(1)> %base, <2 x i8> ret <2 x ptr addrspace(1)> %gep } ;; For unstable pointers we should avoid any introduction of inttoptr define <2 x ptr addrspace(2)> @test_vec_null_base_unstable() { ; CHECK-LABEL: define <2 x ptr addrspace(2)> @test_vec_null_base_unstable() { ; CHECK-NEXT: ret <2 x ptr addrspace(2)> getelementptr (i8, <2 x ptr addrspace(2)> splat (ptr addrspace(2) null), <2 x i8> ) ; %gep = getelementptr i8, <2 x ptr addrspace(2)> , <2 x i8> ret <2 x ptr addrspace(2)> %gep } define <2 x ptr addrspace(2)> @test_vec_inttoptr_base_unstable() { ; CHECK-LABEL: define <2 x ptr addrspace(2)> @test_vec_inttoptr_base_unstable() { ; CHECK-NEXT: ret <2 x ptr addrspace(2)> getelementptr (i8, <2 x ptr addrspace(2)> , <2 x i8> ) ; %base = inttoptr <2 x i16> to <2 x ptr addrspace(2)> %gep = getelementptr i8, <2 x ptr addrspace(2)> %base, <2 x i8> ret <2 x ptr addrspace(2)> %gep } ;; The same is true for pointers with external state: no new inttoptr define <2 x ptr addrspace(3)> @test_vec_null_base_external() { ; CHECK-LABEL: define <2 x ptr addrspace(3)> @test_vec_null_base_external() { ; CHECK-NEXT: ret <2 x ptr addrspace(3)> getelementptr (i8, <2 x ptr addrspace(3)> splat (ptr addrspace(3) null), <2 x i8> ) ; %gep = getelementptr i8, <2 x ptr addrspace(3)> , <2 x i8> ret <2 x ptr addrspace(3)> %gep } define <2 x ptr addrspace(3)> @test_vec_inttoptr_base_external() { ; CHECK-LABEL: define <2 x ptr addrspace(3)> @test_vec_inttoptr_base_external() { ; CHECK-NEXT: ret <2 x ptr addrspace(3)> getelementptr (i8, <2 x ptr addrspace(3)> , <2 x i8> ) ; %base = inttoptr <2 x i16> to <2 x ptr addrspace(3)> %gep = getelementptr i8, <2 x ptr addrspace(3)> %base, <2 x i8> ret <2 x ptr addrspace(3)> %gep }