The legacy PM is deprecated, so update a bunch of lit tests running opt to use the new PM syntax when specifying the pipeline. In this patch focus has been put on test cases for ConstantMerge, ConstraintElimination, CorrelatedValuePropagation, GlobalDCE, GlobalOpt, SCCP, TailCallElim and PredicateInfo. Differential Revision: https://reviews.llvm.org/D114516
237 lines
9.9 KiB
LLVM
237 lines
9.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
|
|
|
|
define i1 @bitcast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
|
|
; CHECK-LABEL: @bitcast_and_cmp(
|
|
; CHECK-NEXT: check.0.min:
|
|
; CHECK-NEXT: [[SRC_C:%.*]] = bitcast i32* [[SRC:%.*]] to i8*
|
|
; CHECK-NEXT: [[MIN_C:%.*]] = bitcast i32* [[MIN:%.*]] to i8*
|
|
; CHECK-NEXT: [[MAX_C:%.*]] = bitcast i32* [[MAX:%.*]] to i16*
|
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
|
|
; CHECK-NEXT: [[GEP_3_C:%.*]] = bitcast i32* [[GEP_3]] to i16*
|
|
; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i8* [[SRC_C]], [[MIN_C]]
|
|
; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i16* [[GEP_3_C]], [[MAX_C]]
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
|
|
; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
|
|
; CHECK: trap:
|
|
; CHECK-NEXT: ret i1 false
|
|
; CHECK: checks:
|
|
; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
|
|
; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]]
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
|
|
; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
|
|
; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true
|
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
|
|
; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
|
|
; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true
|
|
; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
|
|
; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
|
|
; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]]
|
|
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
|
|
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
|
|
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_7]]
|
|
;
|
|
check.0.min:
|
|
%src.c = bitcast i32* %src to i8*
|
|
%min.c = bitcast i32* %min to i8*
|
|
%max.c = bitcast i32* %max to i16*
|
|
|
|
%gep.3 = getelementptr inbounds i32, i32* %src, i64 3
|
|
%gep.3.c = bitcast i32* %gep.3 to i16*
|
|
%c.min.0 = icmp ult i8* %src.c, %min.c
|
|
%c.max.3 = icmp ugt i16* %gep.3.c, %max.c
|
|
|
|
%or = or i1 %c.min.0, %c.max.3
|
|
br i1 %or, label %trap, label %checks
|
|
|
|
trap:
|
|
ret i1 0
|
|
|
|
checks:
|
|
%c.3.min = icmp ult i32* %gep.3, %min
|
|
%c.3.max = icmp ult i32* %gep.3, %max
|
|
%res.1 = xor i1 %c.3.min, %c.3.max
|
|
|
|
%gep.1 = getelementptr inbounds i32, i32* %src, i64 1
|
|
%c.1.min = icmp ult i32* %gep.1, %min
|
|
%c.1.max = icmp ult i32* %gep.1, %max
|
|
%res.2 = xor i1 %c.1.min, %c.1.max
|
|
|
|
%gep.2 = getelementptr inbounds i32, i32* %src, i64 2
|
|
%c.2.min = icmp ult i32* %gep.2, %min
|
|
%c.2.max = icmp ult i32* %gep.2, %max
|
|
%res.3 = xor i1 %c.2.min, %c.2.max
|
|
|
|
%gep.4 = getelementptr inbounds i32, i32* %src, i64 4
|
|
%c.4.min = icmp ult i32* %gep.4, %min
|
|
%c.4.max = icmp ult i32* %gep.4, %max
|
|
%res.4 = xor i1 %c.4.min, %c.4.max
|
|
|
|
%res.5 = xor i1 %res.1, %res.2
|
|
%res.6 = xor i1 %res.5, %res.3
|
|
%res.7 = xor i1 %res.6, %res.4
|
|
|
|
ret i1 %res.7
|
|
}
|
|
|
|
define i1 @gep0_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
|
|
; CHECK-LABEL: @gep0_and_cmp(
|
|
; CHECK-NEXT: check.0.min:
|
|
; CHECK-NEXT: [[SRC_C:%.*]] = getelementptr i32, i32* [[SRC:%.*]], i64 0
|
|
; CHECK-NEXT: [[MIN_C:%.*]] = getelementptr i32, i32* [[MIN:%.*]], i64 0
|
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
|
|
; CHECK-NEXT: [[GEP_3_C:%.*]] = getelementptr i32, i32* [[GEP_3]], i32 0
|
|
; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i32* [[SRC_C]], [[MIN_C]]
|
|
; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i32* [[GEP_3_C]], [[MAX:%.*]]
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
|
|
; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
|
|
; CHECK: trap:
|
|
; CHECK-NEXT: ret i1 false
|
|
; CHECK: checks:
|
|
; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
|
|
; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]]
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
|
|
; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
|
|
; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true
|
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
|
|
; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
|
|
; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true
|
|
; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
|
|
; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
|
|
; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]]
|
|
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
|
|
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
|
|
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_7]]
|
|
;
|
|
check.0.min:
|
|
%src.c = getelementptr i32, i32* %src, i64 0
|
|
%min.c = getelementptr i32, i32* %min, i64 0
|
|
|
|
%gep.3 = getelementptr inbounds i32, i32* %src, i64 3
|
|
%gep.3.c = getelementptr i32, i32* %gep.3, i32 0
|
|
%c.min.0 = icmp ult i32* %src.c, %min.c
|
|
%c.max.3 = icmp ugt i32* %gep.3.c, %max
|
|
|
|
%or = or i1 %c.min.0, %c.max.3
|
|
br i1 %or, label %trap, label %checks
|
|
|
|
trap:
|
|
ret i1 0
|
|
|
|
checks:
|
|
%c.3.min = icmp ult i32* %gep.3, %min
|
|
%c.3.max = icmp ult i32* %gep.3, %max
|
|
%res.1 = xor i1 %c.3.min, %c.3.max
|
|
|
|
%gep.1 = getelementptr inbounds i32, i32* %src, i64 1
|
|
%c.1.min = icmp ult i32* %gep.1, %min
|
|
%c.1.max = icmp ult i32* %gep.1, %max
|
|
%res.2 = xor i1 %c.1.min, %c.1.max
|
|
|
|
%gep.2 = getelementptr inbounds i32, i32* %src, i64 2
|
|
%c.2.min = icmp ult i32* %gep.2, %min
|
|
%c.2.max = icmp ult i32* %gep.2, %max
|
|
%res.3 = xor i1 %c.2.min, %c.2.max
|
|
|
|
%gep.4 = getelementptr inbounds i32, i32* %src, i64 4
|
|
%c.4.min = icmp ult i32* %gep.4, %min
|
|
%c.4.max = icmp ult i32* %gep.4, %max
|
|
%res.4 = xor i1 %c.4.min, %c.4.max
|
|
|
|
%res.5 = xor i1 %res.1, %res.2
|
|
%res.6 = xor i1 %res.5, %res.3
|
|
%res.7 = xor i1 %res.6, %res.4
|
|
|
|
ret i1 %res.7
|
|
}
|
|
|
|
; Should not look through addresspacecast, because it may change the pointer
|
|
; value.
|
|
define i1 @addrspacecast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
|
|
; CHECK-LABEL: @addrspacecast_and_cmp(
|
|
; CHECK-NEXT: check.0.min:
|
|
; CHECK-NEXT: [[SRC_C:%.*]] = addrspacecast i32* [[SRC:%.*]] to i8 addrspace(1)*
|
|
; CHECK-NEXT: [[MIN_C:%.*]] = addrspacecast i32* [[MIN:%.*]] to i8 addrspace(1)*
|
|
; CHECK-NEXT: [[MAX_C:%.*]] = addrspacecast i32* [[MAX:%.*]] to i16 addrspace(1)*
|
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
|
|
; CHECK-NEXT: [[GEP_3_C:%.*]] = addrspacecast i32* [[GEP_3]] to i16 addrspace(1)*
|
|
; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i8 addrspace(1)* [[SRC_C]], [[MIN_C]]
|
|
; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i16 addrspace(1)* [[GEP_3_C]], [[MAX_C]]
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
|
|
; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
|
|
; CHECK: trap:
|
|
; CHECK-NEXT: ret i1 false
|
|
; CHECK: checks:
|
|
; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
|
|
; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_3_MIN]], [[C_3_MAX]]
|
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
|
|
; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
|
|
; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[C_1_MIN]], [[C_1_MAX]]
|
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
|
|
; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
|
|
; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[C_2_MIN]], [[C_2_MAX]]
|
|
; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
|
|
; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
|
|
; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
|
|
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[C_4_MIN]], [[C_4_MAX]]
|
|
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
|
|
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
|
|
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
|
|
; CHECK-NEXT: ret i1 [[RES_7]]
|
|
;
|
|
check.0.min:
|
|
%src.c = addrspacecast i32* %src to i8 addrspace(1)*
|
|
%min.c = addrspacecast i32* %min to i8 addrspace(1)*
|
|
%max.c = addrspacecast i32* %max to i16 addrspace(1)*
|
|
|
|
%gep.3 = getelementptr inbounds i32, i32* %src, i64 3
|
|
%gep.3.c = addrspacecast i32* %gep.3 to i16 addrspace(1) *
|
|
%c.min.0 = icmp ult i8 addrspace(1)* %src.c, %min.c
|
|
%c.max.3 = icmp ugt i16 addrspace(1)* %gep.3.c, %max.c
|
|
|
|
%or = or i1 %c.min.0, %c.max.3
|
|
br i1 %or, label %trap, label %checks
|
|
|
|
trap:
|
|
ret i1 0
|
|
|
|
checks:
|
|
%c.3.min = icmp ult i32* %gep.3, %min
|
|
%c.3.max = icmp ult i32* %gep.3, %max
|
|
%res.1 = xor i1 %c.3.min, %c.3.max
|
|
|
|
%gep.1 = getelementptr inbounds i32, i32* %src, i64 1
|
|
%c.1.min = icmp ult i32* %gep.1, %min
|
|
%c.1.max = icmp ult i32* %gep.1, %max
|
|
%res.2 = xor i1 %c.1.min, %c.1.max
|
|
|
|
%gep.2 = getelementptr inbounds i32, i32* %src, i64 2
|
|
%c.2.min = icmp ult i32* %gep.2, %min
|
|
%c.2.max = icmp ult i32* %gep.2, %max
|
|
%res.3 = xor i1 %c.2.min, %c.2.max
|
|
|
|
%gep.4 = getelementptr inbounds i32, i32* %src, i64 4
|
|
%c.4.min = icmp ult i32* %gep.4, %min
|
|
%c.4.max = icmp ult i32* %gep.4, %max
|
|
%res.4 = xor i1 %c.4.min, %c.4.max
|
|
|
|
%res.5 = xor i1 %res.1, %res.2
|
|
%res.6 = xor i1 %res.5, %res.3
|
|
%res.7 = xor i1 %res.6, %res.4
|
|
|
|
ret i1 %res.7
|
|
}
|