Skip to content

[ConstantFold] Remove notional over-indexing fold #93697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/test/CodeGen/object-size.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void test2(void) {

// CHECK-LABEL: define{{.*}} void @test3
void test3(void) {
// CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 1, i64 37), ptr @.str, i64 0)
// CHECK: = call ptr @__strcpy_chk(ptr getelementptr inbounds ([63 x i8], ptr @gbuf, i64 0, i64 100), ptr @.str, i64 0)
strcpy(&gbuf[100], "Hi there");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,21 @@ std::initializer_list<std::initializer_list<int>> nested = {
// CHECK-DYNAMIC-BE: store i32 {{.*}}, ptr getelementptr inbounds (i32, ptr @_ZGR6nested0_, i64 1)
// CHECK-DYNAMIC-BE: store ptr @_ZGR6nested0_,
// CHECK-DYNAMIC-BE: ptr @_ZGR6nested_, align 8
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([2 x i32], ptr @_ZGR6nested0_, i64 1, i64 0),
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([2 x i32], ptr @_ZGR6nested0_, i64 0, i64 2),
// CHECK-DYNAMIC-BE: ptr getelementptr inbounds ({{.*}}, ptr @_ZGR6nested_, i32 0, i32 1), align 8
// CHECK-DYNAMIC-BE: store i32 3, ptr @_ZGR6nested1_
// CHECK-DYNAMIC-BE: store i32 {{.*}}, ptr getelementptr inbounds (i32, ptr @_ZGR6nested1_, i64 1)
// CHECK-DYNAMIC-BE: store ptr @_ZGR6nested1_,
// CHECK-DYNAMIC-BE: ptr getelementptr inbounds ({{.*}}, ptr @_ZGR6nested_, i64 1), align 8
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([2 x i32], ptr @_ZGR6nested1_, i64 1, i64 0),
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([2 x i32], ptr @_ZGR6nested1_, i64 0, i64 2),
// CHECK-DYNAMIC-BE: ptr getelementptr inbounds ({{.*}}, ptr @_ZGR6nested_, i64 1, i32 1), align 8
// CHECK-DYNAMIC-BE: store i32 5, ptr @_ZGR6nested2_
// CHECK-DYNAMIC-BE: store i32 {{.*}}, ptr getelementptr inbounds (i32, ptr @_ZGR6nested2_, i64 1)
// CHECK-DYNAMIC-BE: store ptr @_ZGR6nested2_,
// CHECK-DYNAMIC-BE: ptr getelementptr inbounds ({{.*}}, ptr @_ZGR6nested_, i64 2), align 8
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([2 x i32], ptr @_ZGR6nested2_, i64 1, i64 0),
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([2 x i32], ptr @_ZGR6nested2_, i64 0, i64 2),
// CHECK-DYNAMIC-BE: ptr getelementptr inbounds ({{.*}}, ptr @_ZGR6nested_, i64 2, i32 1), align 8
// CHECK-DYNAMIC-BE: store ptr @_ZGR6nested_,
// CHECK-DYNAMIC-BE: ptr @nested, align 8
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([3 x {{.*}}], ptr @_ZGR6nested_, i64 1, i64 0),
// CHECK-DYNAMIC-BE: store ptr getelementptr inbounds ([3 x {{.*}}], ptr @_ZGR6nested_, i64 0, i64 3),
// CHECK-DYNAMIC-BE: ptr getelementptr inbounds ({{.*}}, ptr @nested, i32 0, i32 1), align 8
4 changes: 2 additions & 2 deletions clang/test/CodeGenHLSL/cbuf.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ tbuffer A : register(t2, space1) {

float foo() {
// CHECK: load float, ptr @[[CB]], align 4
// CHECK: load double, ptr getelementptr inbounds ({ float, double }, ptr @[[CB]], i32 0, i32 1), align 8
// CHECK: load double, ptr getelementptr ({ float, double }, ptr @[[CB]], i32 0, i32 1), align 8
// CHECK: load float, ptr @[[TB]], align 4
// CHECK: load double, ptr getelementptr inbounds ({ float, double }, ptr @[[TB]], i32 0, i32 1), align 8
// CHECK: load double, ptr getelementptr ({ float, double }, ptr @[[TB]], i32 0, i32 1), align 8
return a + b + c*d;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/linker-wrapper-image.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// OPENMP-REL: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading.relocatable", align 8

// OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading", align 8
// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr inbounds ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr getelementptr inbounds ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }]
// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr getelementptr ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }]
// OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }
// OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
// RUN: echo 'section "__sancov_cntrs"' > patterns.txt
// RUN: echo '%[0-9]\+ = load i8, ptr @__sancov_gen_' >> patterns.txt
// RUN: echo 'store i8 %[0-9]\+, ptr @__sancov_gen_' >> patterns.txt
// RUN: echo '%[0-9]\+ = load i8, ptr getelementptr inbounds (\[[0-9]\+ x i8\], ptr @__sancov_gen_' >> patterns.txt
// RUN: echo 'store i8 %[0-9]\+, ptr getelementptr inbounds (\[[0-9]\+ x i8\], ptr @__sancov_gen_' >> patterns.txt
// RUN: echo '%[0-9]\+ = load i8, ptr getelementptr (\[[0-9]\+ x i8\], ptr @__sancov_gen_' >> patterns.txt
// RUN: echo 'store i8 %[0-9]\+, ptr getelementptr (\[[0-9]\+ x i8\], ptr @__sancov_gen_' >> patterns.txt

// Check indirect-calls
// RUN: echo 'call void @__sanitizer_cov_trace_pc_indir' >> patterns.txt
Expand Down
196 changes: 0 additions & 196 deletions llvm/lib/IR/ConstantFold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1417,50 +1417,6 @@ Constant *llvm::ConstantFoldCompareInstruction(CmpInst::Predicate Predicate,
return nullptr;
}

/// Test whether the given sequence of *normalized* indices is "inbounds".
template<typename IndexTy>
static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) {
// No indices means nothing that could be out of bounds.
if (Idxs.empty()) return true;

// If the first index is zero, it's in bounds.
if (cast<Constant>(Idxs[0])->isNullValue()) return true;

// If the first index is one and all the rest are zero, it's in bounds,
// by the one-past-the-end rule.
if (auto *CI = dyn_cast<ConstantInt>(Idxs[0])) {
if (!CI->isOne())
return false;
} else {
auto *CV = cast<ConstantDataVector>(Idxs[0]);
CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue());
if (!CI || !CI->isOne())
return false;
}

for (unsigned i = 1, e = Idxs.size(); i != e; ++i)
if (!cast<Constant>(Idxs[i])->isNullValue())
return false;
return true;
}

/// Test whether a given ConstantInt is in-range for a SequentialType.
static bool isIndexInRangeOfArrayType(uint64_t NumElements,
const ConstantInt *CI) {
// We cannot bounds check the index if it doesn't fit in an int64_t.
if (CI->getValue().getSignificantBits() > 64)
return false;

// A negative index or an index past the end of our sequential type is
// considered out-of-range.
int64_t IndexVal = CI->getSExtValue();
if (IndexVal < 0 || (IndexVal != 0 && (uint64_t)IndexVal >= NumElements))
return false;

// Otherwise, it is in-range.
return true;
}

// Combine Indices - If the source pointer to this getelementptr instruction
// is a getelementptr instruction, combine the indices of the two
// getelementptr instructions into a single instruction.
Expand Down Expand Up @@ -1572,157 +1528,5 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
if (Constant *C = foldGEPOfGEP(GEP, PointeeTy, InBounds, Idxs))
return C;

// Check to see if any array indices are not within the corresponding
// notional array or vector bounds. If so, try to determine if they can be
// factored out into preceding dimensions.
SmallVector<Constant *, 8> NewIdxs;
Type *Ty = PointeeTy;
Type *Prev = C->getType();
auto GEPIter = gep_type_begin(PointeeTy, Idxs);
bool Unknown =
!isa<ConstantInt>(Idxs[0]) && !isa<ConstantDataVector>(Idxs[0]);
for (unsigned i = 1, e = Idxs.size(); i != e;
Prev = Ty, Ty = (++GEPIter).getIndexedType(), ++i) {
if (!isa<ConstantInt>(Idxs[i]) && !isa<ConstantDataVector>(Idxs[i])) {
// We don't know if it's in range or not.
Unknown = true;
continue;
}
if (!isa<ConstantInt>(Idxs[i - 1]) && !isa<ConstantDataVector>(Idxs[i - 1]))
// Skip if the type of the previous index is not supported.
continue;
if (isa<StructType>(Ty)) {
// The verify makes sure that GEPs into a struct are in range.
continue;
}
if (isa<VectorType>(Ty)) {
// There can be awkward padding in after a non-power of two vector.
Unknown = true;
continue;
}
auto *STy = cast<ArrayType>(Ty);
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
if (isIndexInRangeOfArrayType(STy->getNumElements(), CI))
// It's in range, skip to the next index.
continue;
if (CI->isNegative()) {
// It's out of range and negative, don't try to factor it.
Unknown = true;
continue;
}
} else {
auto *CV = cast<ConstantDataVector>(Idxs[i]);
bool IsInRange = true;
for (unsigned I = 0, E = CV->getNumElements(); I != E; ++I) {
auto *CI = cast<ConstantInt>(CV->getElementAsConstant(I));
IsInRange &= isIndexInRangeOfArrayType(STy->getNumElements(), CI);
if (CI->isNegative()) {
Unknown = true;
break;
}
}
if (IsInRange || Unknown)
// It's in range, skip to the next index.
// It's out of range and negative, don't try to factor it.
continue;
}
if (isa<StructType>(Prev)) {
// It's out of range, but the prior dimension is a struct
// so we can't do anything about it.
Unknown = true;
continue;
}

// Determine the number of elements in our sequential type.
uint64_t NumElements = STy->getArrayNumElements();
if (!NumElements) {
Unknown = true;
continue;
}

// It's out of range, but we can factor it into the prior
// dimension.
NewIdxs.resize(Idxs.size());

// Expand the current index or the previous index to a vector from a scalar
// if necessary.
Constant *CurrIdx = cast<Constant>(Idxs[i]);
auto *PrevIdx =
NewIdxs[i - 1] ? NewIdxs[i - 1] : cast<Constant>(Idxs[i - 1]);
bool IsCurrIdxVector = CurrIdx->getType()->isVectorTy();
bool IsPrevIdxVector = PrevIdx->getType()->isVectorTy();
bool UseVector = IsCurrIdxVector || IsPrevIdxVector;

if (!IsCurrIdxVector && IsPrevIdxVector)
CurrIdx = ConstantDataVector::getSplat(
cast<FixedVectorType>(PrevIdx->getType())->getNumElements(), CurrIdx);

if (!IsPrevIdxVector && IsCurrIdxVector)
PrevIdx = ConstantDataVector::getSplat(
cast<FixedVectorType>(CurrIdx->getType())->getNumElements(), PrevIdx);

Constant *Factor =
ConstantInt::get(CurrIdx->getType()->getScalarType(), NumElements);
if (UseVector)
Factor = ConstantDataVector::getSplat(
IsPrevIdxVector
? cast<FixedVectorType>(PrevIdx->getType())->getNumElements()
: cast<FixedVectorType>(CurrIdx->getType())->getNumElements(),
Factor);

NewIdxs[i] =
ConstantFoldBinaryInstruction(Instruction::SRem, CurrIdx, Factor);

Constant *Div =
ConstantFoldBinaryInstruction(Instruction::SDiv, CurrIdx, Factor);

// We're working on either ConstantInt or vectors of ConstantInt,
// so these should always fold.
assert(NewIdxs[i] != nullptr && Div != nullptr && "Should have folded");

unsigned CommonExtendedWidth =
std::max(PrevIdx->getType()->getScalarSizeInBits(),
Div->getType()->getScalarSizeInBits());
CommonExtendedWidth = std::max(CommonExtendedWidth, 64U);

// Before adding, extend both operands to i64 to avoid
// overflow trouble.
Type *ExtendedTy = Type::getIntNTy(Div->getContext(), CommonExtendedWidth);
if (UseVector)
ExtendedTy = FixedVectorType::get(
ExtendedTy,
IsPrevIdxVector
? cast<FixedVectorType>(PrevIdx->getType())->getNumElements()
: cast<FixedVectorType>(CurrIdx->getType())->getNumElements());

if (!PrevIdx->getType()->isIntOrIntVectorTy(CommonExtendedWidth))
PrevIdx =
ConstantFoldCastInstruction(Instruction::SExt, PrevIdx, ExtendedTy);

if (!Div->getType()->isIntOrIntVectorTy(CommonExtendedWidth))
Div = ConstantFoldCastInstruction(Instruction::SExt, Div, ExtendedTy);

assert(PrevIdx && Div && "Should have folded");
NewIdxs[i - 1] = ConstantExpr::getAdd(PrevIdx, Div);
}

// If we did any factoring, start over with the adjusted indices.
if (!NewIdxs.empty()) {
for (unsigned i = 0, e = Idxs.size(); i != e; ++i)
if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]);
return ConstantExpr::getGetElementPtr(PointeeTy, C, NewIdxs, InBounds,
InRange);
}

// If all indices are known integers and normalized, we can do a simple
// check for the "inbounds" property.
if (!Unknown && !InBounds)
if (auto *GV = dyn_cast<GlobalVariable>(C))
if (!GV->hasExternalWeakLinkage() && GV->getValueType() == PointeeTy &&
isInBoundsIndices(Idxs))
// TODO(gep_nowrap): Can also set NUW here.
return ConstantExpr::getGetElementPtr(
PointeeTy, C, Idxs, GEPNoWrapFlags::inBounds(), InRange);

return nullptr;
}
4 changes: 2 additions & 2 deletions llvm/test/Assembler/ConstantExprFold.ll
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
; CHECK: @mul = global ptr null
; CHECK: @xor = global ptr @A
; CHECK: @B = external global %Ty
; CHECK: @icmp_ult1 = global i1 icmp ugt (ptr getelementptr inbounds (i64, ptr @A, i64 1), ptr @A)
; CHECK: @icmp_ult1 = global i1 icmp ugt (ptr getelementptr (i64, ptr @A, i64 1), ptr @A)
; CHECK: @icmp_slt = global i1 false
; CHECK: @icmp_ult2 = global i1 icmp ugt (ptr getelementptr inbounds (%Ty, ptr @B, i64 0, i32 1), ptr @B)
; CHECK: @icmp_ult2 = global i1 icmp ugt (ptr getelementptr (%Ty, ptr @B, i64 0, i32 1), ptr @B)
; CHECK: @cons = weak global i32 0, align 8
; CHECK: @gep1 = global <2 x ptr> undef
; CHECK: @gep2 = global <2 x ptr> undef
Expand Down
15 changes: 5 additions & 10 deletions llvm/test/Assembler/getelementptr.ll
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
; RUN: verify-uselistorder %s

; Verify that over-indexed getelementptrs are folded.
@A = external global [2 x [3 x [5 x [7 x i32]]]]
@B = global ptr getelementptr ([2 x [3 x [5 x [7 x i32]]]], ptr @A, i64 0, i64 0, i64 2, i64 1, i64 7523)
; CHECK: @B = global ptr getelementptr ([2 x [3 x [5 x [7 x i32]]]], ptr @A, i64 36, i64 0, i64 1, i64 0, i64 5)
; CHECK: @B = global ptr getelementptr ([2 x [3 x [5 x [7 x i32]]]], ptr @A, i64 0, i64 0, i64 2, i64 1, i64 7523)
@C = global ptr getelementptr ([2 x [3 x [5 x [7 x i32]]]], ptr @A, i64 3, i64 2, i64 0, i64 0, i64 7523)
; CHECK: @C = global ptr getelementptr ([2 x [3 x [5 x [7 x i32]]]], ptr @A, i64 39, i64 1, i64 1, i64 4, i64 5)
; CHECK: @C = global ptr getelementptr ([2 x [3 x [5 x [7 x i32]]]], ptr @A, i64 3, i64 2, i64 0, i64 0, i64 7523)

; Verify that constant expression GEPs work with i84 indices.
@D = external global [1 x i32]

@E = global ptr getelementptr inbounds ([1 x i32], ptr @D, i84 0, i64 1)
; CHECK: @E = global ptr getelementptr inbounds ([1 x i32], ptr @D, i84 1, i64 0)
; CHECK: @E = global ptr getelementptr inbounds ([1 x i32], ptr @D, i84 0, i64 1)

; Verify that i16 indices work.
@x = external global {i32, i32}
Expand All @@ -23,16 +22,12 @@
@PR23753_b = global ptr getelementptr (i8, ptr @PR23753_a, i64 ptrtoint (ptr @PR23753_a to i64))
; CHECK: @PR23753_b = global ptr getelementptr (i8, ptr @PR23753_a, i64 ptrtoint (ptr @PR23753_a to i64))

; Verify that inrange doesn't inhibit over-indexed getelementptr folding,
; but does inhibit combining two GEPs where the inner one has inrange (this
; will be done when DataLayout is available instead).

@nestedarray = global [2 x [4 x ptr]] zeroinitializer

; CHECK: @nestedarray.1 = alias ptr, getelementptr inbounds inrange(-32, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i64 1, i32 0)
; CHECK: @nestedarray.1 = alias ptr, getelementptr inbounds inrange(-32, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0, i32 4)
@nestedarray.1 = alias ptr, getelementptr inbounds inrange(-32, 32) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0, i32 4)

; CHECK: @nestedarray.2 = alias ptr, getelementptr inbounds inrange(0, 1) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i64 1, i32 0)
; CHECK: @nestedarray.2 = alias ptr, getelementptr inbounds inrange(0, 1) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0, i32 4)
@nestedarray.2 = alias ptr, getelementptr inbounds inrange(0, 1) ([2 x [4 x ptr]], ptr @nestedarray, i32 0, i32 0, i32 4)

; CHECK: @nestedarray.3 = alias ptr, getelementptr inbounds inrange(0, 4) ([4 x ptr], ptr @nestedarray, i32 0, i32 0)
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Assembler/getelementptr_vec_ce.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
@G = global [4 x i32] zeroinitializer

; CHECK-LABEL: @foo
; CHECK: ret <4 x ptr> getelementptr inbounds ([4 x i32], ptr @G, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>)
; CHECK: ret <4 x ptr> getelementptr ([4 x i32], ptr @G, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>)
define <4 x ptr> @foo() {
ret <4 x ptr> getelementptr ([4 x i32], ptr @G, i32 0, <4 x i32> <i32 0, i32 1, i32 2, i32 3>)
}
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/AMDGPU/opencl-printf.ll
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ entry:
define amdgpu_kernel void @test_indexed_format_str(i32 %n) {
; R600-LABEL: @test_indexed_format_str(
; R600-NEXT: entry:
; R600-NEXT: [[CALL1:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) getelementptr inbounds ([11 x i8], ptr addrspace(4) @indexed.format.str, i64 0, i32 7), i32 [[N:%.*]])
; R600-NEXT: [[CALL1:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) getelementptr ([11 x i8], ptr addrspace(4) @indexed.format.str, i64 0, i32 7), i32 [[N:%.*]])
; R600-NEXT: ret void
;
; GCN-LABEL: @test_indexed_format_str(
Expand Down Expand Up @@ -583,7 +583,7 @@ entry:
define amdgpu_kernel void @test_indexed_format_str_oob(i32 %n) {
; R600-LABEL: @test_indexed_format_str_oob(
; R600-NEXT: entry:
; R600-NEXT: [[CALL1:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) getelementptr inbounds ([11 x i8], ptr addrspace(4) @indexed.format.str, i64 1, i64 0), i32 [[N:%.*]])
; R600-NEXT: [[CALL1:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) getelementptr ([11 x i8], ptr addrspace(4) @indexed.format.str, i64 0, i64 11), i32 [[N:%.*]])
; R600-NEXT: ret void
;
; GCN-LABEL: @test_indexed_format_str_oob(
Expand Down Expand Up @@ -1864,7 +1864,7 @@ entry:
define amdgpu_kernel void @test_print_string_indexed(i32 %n) {
; R600-LABEL: @test_print_string_indexed(
; R600-NEXT: entry:
; R600-NEXT: [[PRINTF:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) @.str, ptr addrspace(4) getelementptr inbounds ([32 x i8], ptr addrspace(4) @printed.str.size32, i64 0, i64 15), i32 [[N:%.*]])
; R600-NEXT: [[PRINTF:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) @.str, ptr addrspace(4) getelementptr ([32 x i8], ptr addrspace(4) @printed.str.size32, i64 0, i64 15), i32 [[N:%.*]])
; R600-NEXT: ret void
;
; GCN-LABEL: @test_print_string_indexed(
Expand Down Expand Up @@ -1900,7 +1900,7 @@ entry:
define amdgpu_kernel void @test_print_string_indexed_oob(i32 %n) {
; R600-LABEL: @test_print_string_indexed_oob(
; R600-NEXT: entry:
; R600-NEXT: [[PRINTF:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) @.str, ptr addrspace(4) getelementptr inbounds ([32 x i8], ptr addrspace(4) @printed.str.size32, i64 1, i64 0), i32 [[N:%.*]])
; R600-NEXT: [[PRINTF:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) @.str, ptr addrspace(4) getelementptr ([32 x i8], ptr addrspace(4) @printed.str.size32, i64 0, i64 32), i32 [[N:%.*]])
; R600-NEXT: ret void
;
; GCN-LABEL: @test_print_string_indexed_oob(
Expand Down
Loading
Loading