llvm-project/llvm/test/Transforms/ConstraintElimination/geps-pointers-to-structs.ll
Florian Hahn 13ffde316a
[ConstraintElim] Remove dead compares after simplification.
Remove compares after replacing all uses. Cleaning dead compares can
enable additional simplifications when adjusting the position of the
pass slightly. In particular, it seems like the additional dead
instructions may prevent SimplifyCFG performing some folds.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D158760
2023-08-24 22:12:57 +01:00

430 lines
18 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
%struct.1 = type { i32, i64, i8 }
%struct.2 = type { i32, [20 x i64], i8 }
define i1 @test.ult.true.due.to.first.dimension(ptr %start, ptr %high) {
; CHECK-LABEL: @test.ult.true.due.to.first.dimension(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 6, i32 0
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 5, i32 0
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 6, i32 0
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 0
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.true.due.to.first.dimension.var.index.0(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @test.ult.true.due.to.first.dimension.var.index.0(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
; CHECK-NEXT: [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT_PLUS_1_EXT]], i32 0
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 0
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext.plus.1 = add nuw nsw i32 %idx, 1
%idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext.plus.1.ext, i32 0
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%idx.ext = zext i32 %idx to i64
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 0
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.true.due.to.first.dimension.var.index.1(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @test.ult.true.due.to.first.dimension.var.index.1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
; CHECK-NEXT: [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT_PLUS_1_EXT]], i32 0
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 1
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext.plus.1 = add nuw nsw i32 %idx, 1
%idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext.plus.1.ext, i32 0
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%idx.ext = zext i32 %idx to i64
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 1
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.true.due.to.first.dimension.var.index.2(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @test.ult.true.due.to.first.dimension.var.index.2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
; CHECK-NEXT: [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT_PLUS_1_EXT]], i32 0
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 2
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext.plus.1 = add nuw nsw i32 %idx, 1
%idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext.plus.1.ext, i32 0
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%idx.ext = zext i32 %idx to i64
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 2
%c.0 = icmp ult ptr %start.0, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.unknown.due.to.first.dimension(ptr %start, ptr %high) {
; CHECK-LABEL: @test.ult.unknown.due.to.first.dimension(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 5, i32 0
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 6, i32 0
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: [[C_0:%.*]] = icmp ult ptr [[START_0_CAST]], [[HIGH]]
; CHECK-NEXT: ret i1 [[C_0]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 0
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 6, i32 0
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.true.due.to.second.dimension(ptr %start, ptr %high) {
; CHECK-LABEL: @test.ult.true.due.to.second.dimension(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 5, i32 2
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 5, i32 1
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 2
%c.1 = icmp ule ptr %add.ptr, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 1
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.unknown.due.to.second.dimension(ptr %start, ptr %high) {
; CHECK-LABEL: @test.ult.unknown.due.to.second.dimension(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 5, i32 2
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 5, i32 2
; CHECK-NEXT: [[C_0:%.*]] = icmp ult ptr [[START_0]], [[HIGH]]
; CHECK-NEXT: ret i1 [[C_0]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 2
%c.1 = icmp ule ptr %add.ptr, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 2
%c.0 = icmp ult ptr %start.0, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.unknown.due.to.second.dimension.var.index.0(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @test.ult.unknown.due.to.second.dimension.var.index.0(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX:%.*]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT]], i32 0
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 1
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: [[C_0:%.*]] = icmp ult ptr [[START_0_CAST]], [[HIGH]]
; CHECK-NEXT: ret i1 [[C_0]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext = zext i32 %idx to i64
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 0
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 1
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @test.ult.unknown.due.to.second.dimension.var.index.1(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @test.ult.unknown.due.to.second.dimension.var.index.1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX:%.*]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT]], i32 1
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 2
; CHECK-NEXT: [[C_0:%.*]] = icmp ult ptr [[START_0]], [[HIGH]]
; CHECK-NEXT: ret i1 [[C_0]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext = zext i32 %idx to i64
%add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 1
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 2
%c.0 = icmp ult ptr %start.0, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @ptr.int.struct.test.ult.true.due.to.first.dimension(ptr %start, ptr %high) {
; CHECK-LABEL: @ptr.int.struct.test.ult.true.due.to.first.dimension(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i32 5
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 0
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i32 5
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 0
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @ptr.int.struct.test.ult.true.due.to.third.dimension.var.index(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @ptr.int.struct.test.ult.true.due.to.third.dimension.var.index(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
; CHECK-NEXT: [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i64 [[IDX_EXT_PLUS_1_EXT]]
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 1, i64 [[IDX_EXT]]
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext.plus.1 = add nuw nsw i32 %idx, 1
%idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
%add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext.plus.1.ext
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%idx.ext = zext i32 %idx to i64
%start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @ptr.int.struct.test.ult.due.to.second.dimension.var.index(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @ptr.int.struct.test.ult.due.to.second.dimension.var.index(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
; CHECK-NEXT: [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i64 [[IDX_EXT_PLUS_1_EXT]]
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 0
; CHECK-NEXT: [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
; CHECK-NEXT: [[C_0:%.*]] = icmp ult ptr [[START_0_CAST]], [[HIGH]]
; CHECK-NEXT: ret i1 [[C_0]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext.plus.1 = add nuw nsw i32 %idx, 1
%idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
%add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext.plus.1.ext
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%idx.ext = zext i32 %idx to i64
%start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 0
%start.0.cast = bitcast ptr %start.0 to ptr
%c.0 = icmp ult ptr %start.0.cast, %high
ret i1 %c.0
if.end:
ret i1 true
}
define i1 @ptr.int.struct.test.ult.unknown.due.to.second.dimension.var.index(ptr %start, ptr %high, i32 %idx) {
; CHECK-LABEL: @ptr.int.struct.test.ult.unknown.due.to.second.dimension.var.index(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
; CHECK-NEXT: [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i64 [[IDX_EXT_PLUS_1_EXT]]
; CHECK-NEXT: [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
; CHECK-NEXT: [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
; CHECK-NEXT: [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 2
; CHECK-NEXT: [[C_0:%.*]] = icmp ult ptr [[START_0]], [[HIGH]]
; CHECK-NEXT: ret i1 [[C_0]]
; CHECK: if.end:
; CHECK-NEXT: ret i1 true
;
entry:
%idx.ext.plus.1 = add nuw nsw i32 %idx, 1
%idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
%add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext.plus.1.ext
%add.ptr.cast = bitcast ptr %add.ptr to ptr
%c.1 = icmp ule ptr %add.ptr.cast, %high
br i1 %c.1, label %if.then, label %if.end
if.then:
%idx.ext = zext i32 %idx to i64
%start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 2
%c.0 = icmp ult ptr %start.0, %high
ret i1 %c.0
if.end:
ret i1 true
}