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
1127 lines
43 KiB
LLVM
1127 lines
43 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
|
|
|
|
target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
|
|
declare ptr @getptr()
|
|
declare void @use(ptr)
|
|
declare void @use.i1(i1)
|
|
|
|
define i1 @eq_base(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @eq_base(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr i8, ptr %x, i64 %y
|
|
%r = icmp eq ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_base_commute(i64 %y) {
|
|
; CHECK-LABEL: @ne_base_commute(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr i8, ptr %x, i64 %y
|
|
%r = icmp ne ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_base_inbounds(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ne_base_inbounds(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
%r = icmp ne ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @eq_base_inbounds_commute(i64 %y) {
|
|
; CHECK-LABEL: @eq_base_inbounds_commute(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
%r = icmp eq ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @slt_base(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @slt_base(
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt ptr [[G]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr i8, ptr %x, i64 %y
|
|
%r = icmp slt ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @sgt_base_commute(i64 %y) {
|
|
; CHECK-LABEL: @sgt_base_commute(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[X]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt ptr [[X]], [[G]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr i8, ptr %x, i64 %y
|
|
%r = icmp sgt ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @slt_base_inbounds(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @slt_base_inbounds(
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr inbounds i8, ptr [[X:%.*]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt ptr [[G]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
%r = icmp slt ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @sgt_base_inbounds_commute(i64 %y) {
|
|
; CHECK-LABEL: @sgt_base_inbounds_commute(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt ptr [[X]], [[G]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
%r = icmp sgt ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ult_base(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ult_base(
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ult ptr [[G]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr i8, ptr %x, i64 %y
|
|
%r = icmp ult ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ugt_base_commute(i64 %y) {
|
|
; CHECK-LABEL: @ugt_base_commute(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[X]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ugt ptr [[X]], [[G]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr i8, ptr %x, i64 %y
|
|
%r = icmp ugt ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ult_base_inbounds(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ult_base_inbounds(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
%r = icmp ult ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ult_base_nusw(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ult_base_nusw(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr nusw i8, ptr %x, i64 %y
|
|
%r = icmp ult ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ugt_base_nuw(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ugt_base_nuw(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr nuw i8, ptr %x, i64 %y
|
|
%r = icmp ugt ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ugt_base_nusw_nuw(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ugt_base_nusw_nuw(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr nusw nuw i8, ptr %x, i64 %y
|
|
%r = icmp ugt ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @uge_base_nuw(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @uge_base_nuw(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%g = getelementptr nuw i8, ptr %x, i64 %y
|
|
%r = icmp uge ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @uge_base_nusw_nuw(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @uge_base_nusw_nuw(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%g = getelementptr nusw nuw i8, ptr %x, i64 %y
|
|
%r = icmp uge ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ugt_base_inbounds_commute(i64 %y) {
|
|
; CHECK-LABEL: @ugt_base_inbounds_commute(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[Y:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
%r = icmp ugt ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_base_inbounds_use(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ne_base_inbounds_use(
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr inbounds i8, ptr [[X:%.*]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[G]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[Y]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
call void @use(ptr %g)
|
|
%r = icmp ne ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @eq_base_inbounds_commute_use(i64 %y) {
|
|
; CHECK-LABEL: @eq_base_inbounds_commute_use(
|
|
; CHECK-NEXT: [[X:%.*]] = call ptr @getptr()
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[G]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[Y]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%x = call ptr @getptr() ; thwart complexity-based canonicalization
|
|
%g = getelementptr inbounds i8, ptr %x, i64 %y
|
|
call void @use(ptr %g)
|
|
%r = icmp eq ptr %x, %g
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_base_inbounds_use_scaled(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ne_base_inbounds_use_scaled(
|
|
; CHECK-NEXT: [[G_IDX:%.*]] = shl nsw i64 [[Y:%.*]], 3
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr inbounds i8, ptr [[X:%.*]], i64 [[G_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[G]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[Y]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr inbounds i64, ptr %x, i64 %y
|
|
call void @use(ptr %g)
|
|
%r = icmp ne ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_base_use_scaled(ptr %x, i64 %y) {
|
|
; CHECK-LABEL: @ne_base_use_scaled(
|
|
; CHECK-NEXT: [[G_IDX_MASK:%.*]] = shl i64 [[Y:%.*]], 3
|
|
; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[G_IDX_MASK]]
|
|
; CHECK-NEXT: call void @use(ptr [[G]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i64 [[G_IDX_MASK]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%g = getelementptr i64, ptr %x, i64 %y
|
|
call void @use(ptr %g)
|
|
%r = icmp ne ptr %g, %x
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @eq_bitcast_base(ptr %p, i64 %x) {
|
|
; CHECK-LABEL: @eq_bitcast_base(
|
|
; CHECK-NEXT: [[GEP_IDX_MASK:%.*]] = and i64 [[X:%.*]], 9223372036854775807
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[GEP_IDX_MASK]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%gep = getelementptr [2 x i8], ptr %p, i64 %x, i64 0
|
|
%r = icmp eq ptr %gep, %p
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @eq_bitcast_base_inbounds(ptr %p, i64 %x) {
|
|
; CHECK-LABEL: @eq_bitcast_base_inbounds(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%gep = getelementptr inbounds [2 x i8], ptr %p, i64 %x, i64 0
|
|
%r = icmp eq ptr %gep, %p
|
|
ret i1 %r
|
|
}
|
|
|
|
@X = global [1000 x i32] zeroinitializer
|
|
|
|
define i1 @PR8882(i64 %i) {
|
|
; CHECK-LABEL: @PR8882(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[I:%.*]], 1000
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%p1 = getelementptr inbounds i32, ptr @X, i64 %i
|
|
%cmp = icmp eq ptr %p1, getelementptr inbounds ([1000 x i32], ptr @X, i64 1, i64 0)
|
|
ret i1 %cmp
|
|
}
|
|
|
|
@X_as1 = addrspace(1) global [1000 x i32] zeroinitializer
|
|
|
|
define i1 @test24_as1(i64 %i) {
|
|
; CHECK-LABEL: @test24_as1(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1:%.*]], 1000
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%p1 = getelementptr inbounds i32, ptr addrspace(1) @X_as1, i64 %i
|
|
%cmp = icmp eq ptr addrspace(1) %p1, getelementptr inbounds ([1000 x i32], ptr addrspace(1) @X_as1, i64 1, i64 0)
|
|
ret i1 %cmp
|
|
}
|
|
|
|
; PR16244
|
|
define i1 @test71(ptr %x) {
|
|
; CHECK-LABEL: @test71(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%a = getelementptr i8, ptr %x, i64 8
|
|
%b = getelementptr inbounds i8, ptr %x, i64 8
|
|
%c = icmp ugt ptr %a, %b
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test71_as1(ptr addrspace(1) %x) {
|
|
; CHECK-LABEL: @test71_as1(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%a = getelementptr i8, ptr addrspace(1) %x, i64 8
|
|
%b = getelementptr inbounds i8, ptr addrspace(1) %x, i64 8
|
|
%c = icmp ugt ptr addrspace(1) %a, %b
|
|
ret i1 %c
|
|
}
|
|
|
|
declare i32 @test58_d(i64)
|
|
|
|
define i1 @test59(ptr %foo) {
|
|
; CHECK-LABEL: @test59(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO:%.*]], i64 8
|
|
; CHECK-NEXT: [[USE:%.*]] = ptrtoint ptr [[GEP1]] to i64
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %foo, i64 2
|
|
%gep2 = getelementptr inbounds i8, ptr %foo, i64 10
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
%use = ptrtoint ptr %gep1 to i64
|
|
%call = call i32 @test58_d(i64 %use)
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test59_as1(ptr addrspace(1) %foo) {
|
|
; CHECK-LABEL: @test59_as1(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[FOO:%.*]], i16 8
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[GEP1]] to i16
|
|
; CHECK-NEXT: [[USE:%.*]] = zext i16 [[TMP1]] to i64
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 [[USE]])
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i64 2
|
|
%gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i64 10
|
|
%cmp = icmp ult ptr addrspace(1) %gep1, %gep2
|
|
%use = ptrtoint ptr addrspace(1) %gep1 to i64
|
|
%call = call i32 @test58_d(i64 %use)
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_nusw(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_nusw(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nusw i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr nusw i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_nusw_inbounds(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_nusw_inbounds(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nusw i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_nuw(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_nuw(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[GEP1_IDX]], [[J:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr nuw i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_nusw_nuw(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_nusw_nuw(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw nsw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i64 [[GEP1_IDX]], [[J:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nusw nuw i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr nusw nuw i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_nusw_nuw_mix(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_nusw_nuw_mix(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw [4 x i8], ptr [[FOO:%.*]], i64 [[I:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw i8, ptr [[FOO]], i64 [[J:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP1]], [[GEP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr nusw i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test_gep_ult_no_inbounds(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test_gep_ult_no_inbounds(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [4 x i8], ptr [[FOO:%.*]], i64 [[I:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[FOO]], i64 [[J:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP1]], [[GEP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test_gep_eq_no_inbounds(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test_gep_eq_no_inbounds(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_IDX]], [[J:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr i8, ptr %foo, i64 %j
|
|
%cmp = icmp eq ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_as1(ptr addrspace(1) %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_as1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[I:%.*]] to i16
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[TMP1]], 2
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[J:%.*]] to i16
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr addrspace(1) %foo, i64 %i
|
|
%gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i64 %j
|
|
%cmp = icmp ult ptr addrspace(1) %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
; Same as test60, but look through an addrspacecast instead of a
|
|
; bitcast. This uses the same sized addrspace.
|
|
define i1 @test60_addrspacecast(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_addrspacecast(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[J:%.*]], [[GEP1_IDX]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%bit = addrspacecast ptr %foo to ptr addrspace(3)
|
|
%gep1 = getelementptr inbounds i32, ptr addrspace(3) %bit, i64 %i
|
|
%gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
|
|
%cast1 = addrspacecast ptr addrspace(3) %gep1 to ptr
|
|
%cmp = icmp ult ptr %cast1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_addrspacecast_smaller(ptr %foo, i16 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_addrspacecast_smaller(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%bit = addrspacecast ptr %foo to ptr addrspace(1)
|
|
%gep1 = getelementptr inbounds i32, ptr addrspace(1) %bit, i16 %i
|
|
%gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
|
|
%cast1 = addrspacecast ptr addrspace(1) %gep1 to ptr
|
|
%cmp = icmp ult ptr %cast1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_addrspacecast_larger(ptr addrspace(1) %foo, i32 %i, i16 %j) {
|
|
; CHECK-LABEL: @test60_addrspacecast_larger(
|
|
; CHECK-NEXT: [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i16 [[I_TR]], 2
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[J:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%bit = addrspacecast ptr addrspace(1) %foo to ptr addrspace(2)
|
|
%gep1 = getelementptr inbounds i32, ptr addrspace(2) %bit, i32 %i
|
|
%gep2 = getelementptr inbounds i8, ptr addrspace(1) %foo, i16 %j
|
|
%cast1 = addrspacecast ptr addrspace(2) %gep1 to ptr addrspace(1)
|
|
%cmp = icmp ult ptr addrspace(1) %cast1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test61(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test61(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [4 x i8], ptr [[FOO:%.*]], i64 [[I:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[FOO]], i64 [[J:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP1]], [[GEP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr i8, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
; Don't transform non-inbounds GEPs.
|
|
}
|
|
|
|
define i1 @test61_as1(ptr addrspace(1) %foo, i16 %i, i16 %j) {
|
|
; CHECK-LABEL: @test61_as1(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [4 x i8], ptr addrspace(1) [[FOO:%.*]], i16 [[I:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr addrspace(1) [[FOO]], i16 [[J:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr addrspace(1) [[GEP1]], [[GEP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr addrspace(1) %foo, i16 %i
|
|
%gep2 = getelementptr i8, ptr addrspace(1) %foo, i16 %j
|
|
%cmp = icmp ult ptr addrspace(1) %gep1, %gep2
|
|
ret i1 %cmp
|
|
; Don't transform non-inbounds GEPs.
|
|
}
|
|
|
|
define i1 @test60_extra_use(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_extra_use(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 [[GEP1_IDX]]
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[J:%.*]], 1
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 [[GEP2_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: call void @use(ptr [[GEP2]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %foo, i64 %i
|
|
%gep2 = getelementptr inbounds i16, ptr %foo, i64 %j
|
|
call void @use(ptr %gep1)
|
|
call void @use(ptr %gep2)
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_extra_use_const_operands_inbounds(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_extra_use_const_operands_inbounds(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO:%.*]], i64 4
|
|
; CHECK-NEXT: call void @use(ptr nonnull [[GEP1]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[J:%.*]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %foo, i64 1
|
|
%gep2 = getelementptr inbounds i16, ptr %foo, i64 %j
|
|
call void @use(ptr %gep1)
|
|
%cmp = icmp eq ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test60_extra_use_const_operands_no_inbounds(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test60_extra_use_const_operands_no_inbounds(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[FOO:%.*]], i64 4
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: [[GEP2_IDX_MASK:%.*]] = and i64 [[J:%.*]], 9223372036854775807
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP2_IDX_MASK]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %foo, i64 1
|
|
%gep2 = getelementptr i16, ptr %foo, i64 %j
|
|
call void @use(ptr %gep1)
|
|
%cmp = icmp eq ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define void @test60_extra_use_fold(ptr %foo, i64 %start.idx, i64 %end.offset) {
|
|
; CHECK-LABEL: @test60_extra_use_fold(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[START_IDX:%.*]], 2
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 [[GEP1_IDX]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 [[END_OFFSET:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: call void @use(ptr [[GEP2]])
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i64 [[GEP1_IDX]], [[END_OFFSET]]
|
|
; CHECK-NEXT: call void @use.i1(i1 [[CMP1]])
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[GEP1_IDX]], [[END_OFFSET]]
|
|
; CHECK-NEXT: call void @use.i1(i1 [[CMP2]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %foo, i64 %start.idx
|
|
%gep2 = getelementptr inbounds i8, ptr %foo, i64 %end.offset
|
|
call void @use(ptr %gep1)
|
|
call void @use(ptr %gep2)
|
|
%cmp1 = icmp eq ptr %gep1, %gep2
|
|
call void @use.i1(i1 %cmp1)
|
|
%cmp2 = icmp ult ptr %gep1, %gep2
|
|
call void @use.i1(i1 %cmp2)
|
|
ret void
|
|
}
|
|
|
|
define i1 @test_scalable_same(ptr %x) {
|
|
; CHECK-LABEL: @test_scalable_same(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[A_IDX:%.*]] = shl i64 [[TMP1]], 5
|
|
; CHECK-NEXT: [[A:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[A_IDX]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[B_IDX:%.*]] = shl i64 [[TMP2]], 5
|
|
; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, ptr [[X]], i64 [[B_IDX]]
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt ptr [[A]], [[B]]
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%a = getelementptr <vscale x 4 x i8>, ptr %x, i64 8
|
|
%b = getelementptr inbounds <vscale x 4 x i8>, ptr %x, i64 8
|
|
%c = icmp ugt ptr %a, %b
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_scalable_x(ptr %x) {
|
|
; CHECK-LABEL: @test_scalable_x(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[A_IDX_MASK:%.*]] = and i64 [[TMP1]], 576460752303423487
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[A_IDX_MASK]], 0
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%a = getelementptr <vscale x 4 x i8>, ptr %x, i64 8
|
|
%c = icmp eq ptr %a, %x
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_scalable_xc(ptr %x) {
|
|
; CHECK-LABEL: @test_scalable_xc(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[A_IDX_MASK:%.*]] = and i64 [[TMP1]], 576460752303423487
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[A_IDX_MASK]], 0
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%a = getelementptr <vscale x 4 x i8>, ptr %x, i64 8
|
|
%c = icmp eq ptr %x, %a
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @test_scalable_xy(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test_scalable_xy(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[TMP1]], 4
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = mul nsw i64 [[I:%.*]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shl nuw i64 [[TMP3]], 2
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = mul nsw i64 [[J:%.*]], [[TMP4]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[GEP2_IDX]], [[GEP1_IDX]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%bit = addrspacecast ptr %foo to ptr addrspace(3)
|
|
%gep1 = getelementptr inbounds <vscale x 4 x i32>, ptr addrspace(3) %bit, i64 %i
|
|
%gep2 = getelementptr inbounds <vscale x 4 x i8>, ptr %foo, i64 %j
|
|
%cast1 = addrspacecast ptr addrspace(3) %gep1 to ptr
|
|
%cmp = icmp ult ptr %cast1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @test_scalable_ij(ptr %foo, i64 %i, i64 %j) {
|
|
; CHECK-LABEL: @test_scalable_ij(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[TMP1]], 4
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = mul nsw i64 [[I:%.*]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.vscale.i64()
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shl nuw i64 [[TMP3]], 2
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = mul nsw i64 [[J:%.*]], [[TMP4]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds <vscale x 4 x i32>, ptr %foo, i64 %i
|
|
%gep2 = getelementptr inbounds <vscale x 4 x i8>, ptr %foo, i64 %j
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_nuw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
|
|
; CHECK-LABEL: @gep_nuw(
|
|
; CHECK-NEXT: [[GEP1_SPLIT_IDX:%.*]] = shl nuw i64 [[A:%.*]], 2
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[B:%.*]], 1
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[GEP1_SPLIT_IDX]], [[GEP1_IDX]]
|
|
; CHECK-NEXT: [[GEP2_SPLIT_IDX:%.*]] = shl nuw i64 [[C:%.*]], 3
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[D:%.*]], 2
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add nuw i64 [[GEP2_SPLIT_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw [2 x i16], ptr %p, i64 %a, i64 %b
|
|
%gep2 = getelementptr nuw [2 x i32], ptr %p, i64 %c, i64 %d
|
|
%cmp = icmp eq ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_nusw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
|
|
; CHECK-LABEL: @gep_nusw(
|
|
; CHECK-NEXT: [[GEP1_SPLIT_IDX:%.*]] = shl nsw i64 [[A:%.*]], 2
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[B:%.*]], 1
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_SPLIT_IDX]], [[GEP1_IDX]]
|
|
; CHECK-NEXT: [[GEP2_SPLIT_IDX:%.*]] = shl nsw i64 [[C:%.*]], 3
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[D:%.*]], 2
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[GEP2_SPLIT_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nusw [2 x i16], ptr %p, i64 %a, i64 %b
|
|
%gep2 = getelementptr nusw [2 x i32], ptr %p, i64 %c, i64 %d
|
|
%cmp = icmp eq ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @pointer_icmp_aligned_with_offset(ptr align 8 %a, ptr align 8 %a2) {
|
|
; CHECK-LABEL: @pointer_icmp_aligned_with_offset(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%gep = getelementptr i8, ptr %a, i64 4
|
|
%cmp = icmp eq ptr %gep, %a2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @pointer_icmp_aligned_with_offset_negative(ptr align 8 %a, ptr align 8 %a2) {
|
|
; CHECK-LABEL: @pointer_icmp_aligned_with_offset_negative(
|
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP]], [[A2:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep = getelementptr i8, ptr %a, i64 8
|
|
%cmp = icmp eq ptr %gep, %a2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_diff_base_same_indices(ptr %x, ptr %y, i64 %z) {
|
|
; CHECK-LABEL: @gep_diff_base_same_indices(
|
|
; CHECK-NEXT: [[X:%.*]] = getelementptr i8, ptr [[X1:%.*]], i64 [[Z:%.*]]
|
|
; CHECK-NEXT: [[Y:%.*]] = getelementptr i8, ptr [[Y1:%.*]], i64 [[Z]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i8, ptr %x, i64 %z
|
|
%gep2 = getelementptr i8, ptr %y, i64 %z
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_diff_base_same_indices_nuw(ptr %x, ptr %y, i64 %z) {
|
|
; CHECK-LABEL: @gep_diff_base_same_indices_nuw(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i8, ptr %x, i64 %z
|
|
%gep2 = getelementptr nuw i8, ptr %y, i64 %z
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_diff_base_same_indices_nusw(ptr %x, ptr %y, i64 %z) {
|
|
; CHECK-LABEL: @gep_diff_base_same_indices_nusw(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nusw i8, ptr %x, i64 %z
|
|
%gep2 = getelementptr nusw i8, ptr %y, i64 %z
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_diff_base_same_indices_nuw_nusw(ptr %x, ptr %y, i64 %z) {
|
|
; CHECK-LABEL: @gep_diff_base_same_indices_nuw_nusw(
|
|
; CHECK-NEXT: [[X:%.*]] = getelementptr nuw i8, ptr [[X1:%.*]], i64 [[Z:%.*]]
|
|
; CHECK-NEXT: [[Y:%.*]] = getelementptr nusw i8, ptr [[Y1:%.*]], i64 [[Z]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i8, ptr %x, i64 %z
|
|
%gep2 = getelementptr nusw i8, ptr %y, i64 %z
|
|
%cmp = icmp ult ptr %gep1, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_eq(ptr %base, i64 %idx, i64 %idx2) {
|
|
; CHECK-LABEL: @gep_multiple_eq(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[DOTMASK:%.*]] = and i64 [[GEP1_IDX1]], 4611686018427387903
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[DOTMASK]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
%cmp = icmp eq ptr %gep2, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_eq_commuted(ptr %base, i64 %idx, i64 %idx2) {
|
|
; CHECK-LABEL: @gep_multiple_eq_commuted(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[DOTMASK:%.*]] = and i64 [[GEP1_IDX1]], 4611686018427387903
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[DOTMASK]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
%cmp = icmp eq ptr %base, %gep2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_mugtiple_ugt_nuw(ptr %base, i64 %idx, i64 %idx2) {
|
|
; CHECK-LABEL: @gep_mugtiple_ugt_nuw(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = sub i64 0, [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[IDX:%.*]], [[GEP1_IDX1]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx
|
|
%gep2 = getelementptr nuw i32, ptr %gep1, i64 %idx2
|
|
%cmp = icmp ugt ptr %gep2, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_mugtiple_ugt_not_all_nuw(ptr %base, i64 %idx, i64 %idx2) {
|
|
; CHECK-LABEL: @gep_mugtiple_ugt_not_all_nuw(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw [4 x i8], ptr [[BASE:%.*]], i64 [[IDX:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr [4 x i8], ptr [[GEP1]], i64 [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[GEP2]], [[BASE]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
%cmp = icmp ugt ptr %gep2, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_mugtiple_ugt_inbounds_nusw(ptr %base, i64 %idx, i64 %idx2) {
|
|
; CHECK-LABEL: @gep_mugtiple_ugt_inbounds_nusw(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[BASE:%.*]], i64 [[IDX:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw [4 x i8], ptr [[GEP1]], i64 [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[GEP2]], [[BASE]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %base, i64 %idx
|
|
%gep2 = getelementptr nusw i32, ptr %gep1, i64 %idx2
|
|
%cmp = icmp ugt ptr %gep2, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_multi_use_below_limit(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3) {
|
|
; CHECK-LABEL: @gep_multiple_multi_use_below_limit(
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2:%.*]], i64 [[GEP3_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
|
|
; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[GEP3]], i64 [[GEP2_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP4]])
|
|
; CHECK-NEXT: [[GEP3_IDX1:%.*]] = shl i64 [[IDX4:%.*]], 2
|
|
; CHECK-NEXT: [[GEP5:%.*]] = getelementptr i8, ptr [[GEP4]], i64 [[GEP3_IDX1]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP5]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP3_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[GEP3_IDX1]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx1
|
|
call void @use(ptr %gep1)
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
call void @use(ptr %gep2)
|
|
%gep3 = getelementptr i32, ptr %gep2, i64 %idx3
|
|
call void @use(ptr %gep3)
|
|
%cmp = icmp eq ptr %gep3, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_multi_use_below_limit_extra_one_use_gep1(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_multiple_multi_use_below_limit_extra_one_use_gep1(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl i64 [[IDX1:%.*]], 2
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[GEP1_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 [[GEP2_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP2]])
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[GEP3_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: [[GEP4_IDX_NEG:%.*]] = mul i64 [[IDX4:%.*]], -4
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[GEP3_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP2]], [[GEP4_IDX_NEG]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx1
|
|
call void @use(ptr %gep1)
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
call void @use(ptr %gep2)
|
|
%gep3 = getelementptr i32, ptr %gep2, i64 %idx3
|
|
call void @use(ptr %gep3)
|
|
%gep4 = getelementptr i32, ptr %gep3, i64 %idx4
|
|
%cmp = icmp eq ptr %gep4, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_multi_use_below_limit_extra_one_use_gep2(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_multiple_multi_use_below_limit_extra_one_use_gep2(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[GEP1_IDX1]], 2
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[TMP1]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP2]])
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[GEP3_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX4:%.*]], 2
|
|
; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[GEP3]], i64 [[GEP4_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP4]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[GEP3_IDX]]
|
|
; CHECK-NEXT: [[GEP4_IDX_NEG:%.*]] = sub i64 0, [[GEP4_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP2]], [[GEP4_IDX_NEG]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
call void @use(ptr %gep2)
|
|
%gep3 = getelementptr i32, ptr %gep2, i64 %idx3
|
|
call void @use(ptr %gep3)
|
|
%gep4 = getelementptr i32, ptr %gep3, i64 %idx4
|
|
call void @use(ptr %gep4)
|
|
%cmp = icmp eq ptr %gep4, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_multi_above_below_limit_consts(ptr %base, i64 %idx1, i64 %idx2) {
|
|
; CHECK-LABEL: @gep_multiple_multi_above_below_limit_consts(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 16
|
|
; CHECK-NEXT: call void @use(ptr [[GEP1]])
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr [4 x i8], ptr [[GEP1]], i64 [[IDX1:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP2]])
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 16
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: [[GEP4:%.*]] = getelementptr [4 x i8], ptr [[GEP3]], i64 [[IDX2:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP4]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP4]], [[BASE]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 4
|
|
call void @use(ptr %gep1)
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx1
|
|
call void @use(ptr %gep2)
|
|
%gep3 = getelementptr i32, ptr %gep2, i64 4
|
|
call void @use(ptr %gep3)
|
|
%gep4 = getelementptr i32, ptr %gep3, i64 %idx2
|
|
call void @use(ptr %gep4)
|
|
%cmp = icmp eq ptr %gep4, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_multiple_multi_use_above_limit(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_multiple_multi_use_above_limit(
|
|
; CHECK-NEXT: [[GEP4:%.*]] = getelementptr [4 x i8], ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP4]])
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr [4 x i8], ptr [[GEP4]], i64 [[IDX2:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: [[GEP5:%.*]] = getelementptr [4 x i8], ptr [[GEP3]], i64 [[IDX3:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP5]])
|
|
; CHECK-NEXT: [[GEP6:%.*]] = getelementptr [4 x i8], ptr [[GEP5]], i64 [[IDX4:%.*]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP6]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP6]], [[BASE]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx1
|
|
call void @use(ptr %gep1)
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
call void @use(ptr %gep2)
|
|
%gep3 = getelementptr i32, ptr %gep2, i64 %idx3
|
|
call void @use(ptr %gep3)
|
|
%gep4 = getelementptr i32, ptr %gep3, i64 %idx4
|
|
call void @use(ptr %gep4)
|
|
%cmp = icmp eq ptr %gep4, %base
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_eq(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_eq(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[GEP3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]
|
|
; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i64 [[GEP1_IDX1]], [[GEP3_IDX2]]
|
|
; CHECK-NEXT: [[CMP_MASK:%.*]] = and i64 [[CMP_UNSHIFTED]], 4611686018427387903
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CMP_MASK]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr i32, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr i32, ptr %gep3, i64 %idx4
|
|
%cmp = icmp eq ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_eq_nuw(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_eq_nuw(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[GEP3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_IDX1]], [[GEP3_IDX2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr nuw i32, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr nuw i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr nuw i32, ptr %gep3, i64 %idx4
|
|
%cmp = icmp eq ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_eq_nuw_different_scales(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_eq_nuw_different_scales(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[IDX1:%.*]], 2
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[IDX2:%.*]], 3
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nuw i64 [[IDX3:%.*]], 2
|
|
; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl nuw i64 [[IDX4:%.*]], 3
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add nuw i64 [[GEP3_IDX]], [[GEP4_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr nuw i64, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr nuw i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr nuw i64, ptr %gep3, i64 %idx4
|
|
%cmp = icmp eq ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_eq_partial_nuw_different_scales(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_eq_partial_nuw_different_scales(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[IDX1:%.*]], 2
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[IDX2:%.*]], 3
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nuw i64 [[IDX3:%.*]], 2
|
|
; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX4:%.*]], 3
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[GEP3_IDX]], [[GEP4_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr nuw i64, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr nuw i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr i64, ptr %gep3, i64 %idx4
|
|
%cmp = icmp eq ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_eq_partial_inbounds_different_scales(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_eq_partial_inbounds_different_scales(
|
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2
|
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 3
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nsw i64 [[IDX3:%.*]], 2
|
|
; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX4:%.*]], 3
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[GEP3_IDX]], [[GEP4_IDX]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr inbounds i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr inbounds i64, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr inbounds i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr i64, ptr %gep3, i64 %idx4
|
|
%cmp = icmp eq ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_ult_nuw(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_ult_nuw(
|
|
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[GEP3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[GEP1_IDX1]], [[GEP3_IDX2]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr nuw i32, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr nuw i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr nuw i32, ptr %gep3, i64 %idx4
|
|
%cmp = icmp ult ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_ult_missing_nuw(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_ult_missing_nuw(
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw [4 x i8], ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
|
|
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw [4 x i8], ptr [[GEP1]], i64 [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw [4 x i8], ptr [[BASE]], i64 [[IDX3:%.*]]
|
|
; CHECK-NEXT: [[GEP4:%.*]] = getelementptr [4 x i8], ptr [[GEP3]], i64 [[IDX4:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP2]], [[GEP4]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr nuw i32, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr nuw i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr i32, ptr %gep3, i64 %idx4
|
|
%cmp = icmp ult ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @gep_gep_multiple_ult_nuw_multi_use(ptr %base, i64 %idx1, i64 %idx2, i64 %idx3, i64 %idx4) {
|
|
; CHECK-LABEL: @gep_gep_multiple_ult_nuw_multi_use(
|
|
; CHECK-NEXT: [[IDX3:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
|
|
; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nuw i64 [[IDX3]], 2
|
|
; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[BASE:%.*]], i64 [[GEP3_IDX]]
|
|
; CHECK-NEXT: [[IDX4:%.*]] = add i64 [[IDX5:%.*]], [[IDX6:%.*]]
|
|
; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl nuw i64 [[IDX4]], 2
|
|
; CHECK-NEXT: [[GEP5:%.*]] = getelementptr nuw i8, ptr [[BASE]], i64 [[GEP4_IDX]]
|
|
; CHECK-NEXT: call void @use(ptr [[GEP3]])
|
|
; CHECK-NEXT: call void @use(ptr [[GEP5]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[GEP3_IDX]], [[GEP4_IDX]]
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%gep1 = getelementptr nuw i32, ptr %base, i64 %idx1
|
|
%gep2 = getelementptr nuw i32, ptr %gep1, i64 %idx2
|
|
%gep3 = getelementptr nuw i32, ptr %base, i64 %idx3
|
|
%gep4 = getelementptr nuw i32, ptr %gep3, i64 %idx4
|
|
call void @use(ptr %gep2)
|
|
call void @use(ptr %gep4)
|
|
%cmp = icmp ult ptr %gep2, %gep4
|
|
ret i1 %cmp
|
|
}
|