[ConstraintElimination] Require GEPs to be inbounds for decomposition.

During decomposition, we assume the no-wrap properties of inbound GEPs.
Make sure the decomposed GEP is actually inbounds.
This commit is contained in:
Florian Hahn 2021-02-07 11:07:49 +00:00
parent 5f8ed1b220
commit 853c52c988
No known key found for this signature in database
GPG Key ID: 61D7554B5CECDC0D
3 changed files with 11 additions and 11 deletions

View File

@ -53,7 +53,7 @@ static SmallVector<std::pair<int64_t, Value *>, 4> decompose(Value *V) {
return {{CI->getSExtValue(), nullptr}}; return {{CI->getSExtValue(), nullptr}};
} }
auto *GEP = dyn_cast<GetElementPtrInst>(V); auto *GEP = dyn_cast<GetElementPtrInst>(V);
if (GEP && GEP->getNumOperands() == 2) { if (GEP && GEP->getNumOperands() == 2 && GEP->isInBounds()) {
if (isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) { if (isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) {
return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1)) return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))
->getSExtValue(), ->getSExtValue(),

View File

@ -151,7 +151,7 @@ define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(i8* %sr
; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr i8, i8* [[SRC]], i16 1 ; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr i8, i8* [[SRC]], i16 1
; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]] ; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]] ; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false ; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] ; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
; CHECK: exit: ; CHECK: exit:
; CHECK-NEXT: ret i4 3 ; CHECK-NEXT: ret i4 3

View File

@ -106,7 +106,7 @@ define i32 @test.ult_no_inbounds(i32* readonly %src, i32* readnone %min, i32* re
; CHECK-NEXT: [[L0:%.*]] = load i32, i32* [[SRC]], align 4 ; CHECK-NEXT: [[L0:%.*]] = load i32, i32* [[SRC]], align 4
; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr i32, i32* [[SRC]], i64 3 ; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr i32, i32* [[SRC]], i64 3
; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I36]], [[MIN]] ; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I36]], [[MIN]]
; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_3_MAX:%.*]] ; CHECK-NEXT: br i1 [[C_3_MIN]], label [[TRAP]], label [[CHECK_3_MAX:%.*]]
; CHECK: check.3.max: ; CHECK: check.3.max:
; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I36]], [[MAX]] ; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I36]], [[MAX]]
; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]] ; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]]
@ -114,18 +114,18 @@ define i32 @test.ult_no_inbounds(i32* readonly %src, i32* readnone %min, i32* re
; CHECK-NEXT: [[L1:%.*]] = load i32, i32* [[ADD_PTR_I36]], align 4 ; CHECK-NEXT: [[L1:%.*]] = load i32, i32* [[ADD_PTR_I36]], align 4
; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr i32, i32* [[SRC]], i64 1 ; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr i32, i32* [[SRC]], i64 1
; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I29]], [[MIN]] ; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I29]], [[MIN]]
; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_1_MAX:%.*]] ; CHECK-NEXT: br i1 [[C_1_MIN]], label [[TRAP]], label [[CHECK_1_MAX:%.*]]
; CHECK: check.1.max: ; CHECK: check.1.max:
; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I29]], [[MAX]] ; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I29]], [[MAX]]
; CHECK-NEXT: br i1 true, label [[CHECK_2_MIN:%.*]], label [[TRAP]] ; CHECK-NEXT: br i1 [[C_1_MAX]], label [[CHECK_2_MIN:%.*]], label [[TRAP]]
; CHECK: check.2.min: ; CHECK: check.2.min:
; CHECK-NEXT: [[L2:%.*]] = load i32, i32* [[ADD_PTR_I29]], align 4 ; CHECK-NEXT: [[L2:%.*]] = load i32, i32* [[ADD_PTR_I29]], align 4
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i32, i32* [[SRC]], i64 2 ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i32, i32* [[SRC]], i64 2
; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I]], [[MIN]] ; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[ADD_PTR_I]], [[MIN]]
; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_2_MAX:%.*]] ; CHECK-NEXT: br i1 [[C_2_MIN]], label [[TRAP]], label [[CHECK_2_MAX:%.*]]
; CHECK: check.2.max: ; CHECK: check.2.max:
; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I]], [[MAX]] ; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[ADD_PTR_I]], [[MAX]]
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[TRAP]] ; CHECK-NEXT: br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]]
; CHECK: exit: ; CHECK: exit:
; CHECK-NEXT: [[L3:%.*]] = load i32, i32* [[ADD_PTR_I]], align 4 ; CHECK-NEXT: [[L3:%.*]] = load i32, i32* [[ADD_PTR_I]], align 4
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]] ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]]
@ -245,16 +245,16 @@ define void @test.not.uge.ult_no_inbounds(i8* %start, i8* %low, i8* %high) {
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; CHECK: if.end: ; CHECK: if.end:
; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8* [[START]], [[HIGH]] ; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8* [[START]], [[HIGH]]
; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 [[T_0]])
; CHECK-NEXT: [[START_1:%.*]] = getelementptr i8, i8* [[START]], i64 1 ; CHECK-NEXT: [[START_1:%.*]] = getelementptr i8, i8* [[START]], i64 1
; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8* [[START_1]], [[HIGH]] ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8* [[START_1]], [[HIGH]]
; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 [[T_1]])
; CHECK-NEXT: [[START_2:%.*]] = getelementptr i8, i8* [[START]], i64 2 ; CHECK-NEXT: [[START_2:%.*]] = getelementptr i8, i8* [[START]], i64 2
; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8* [[START_2]], [[HIGH]] ; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8* [[START_2]], [[HIGH]]
; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 [[T_2]])
; CHECK-NEXT: [[START_3:%.*]] = getelementptr i8, i8* [[START]], i64 3 ; CHECK-NEXT: [[START_3:%.*]] = getelementptr i8, i8* [[START]], i64 3
; CHECK-NEXT: [[T_3:%.*]] = icmp ult i8* [[START_3]], [[HIGH]] ; CHECK-NEXT: [[T_3:%.*]] = icmp ult i8* [[START_3]], [[HIGH]]
; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 [[T_3]])
; CHECK-NEXT: [[START_4:%.*]] = getelementptr i8, i8* [[START]], i64 4 ; CHECK-NEXT: [[START_4:%.*]] = getelementptr i8, i8* [[START]], i64 4
; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8* [[START_4]], [[HIGH]] ; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8* [[START_4]], [[HIGH]]
; CHECK-NEXT: call void @use(i1 [[C_4]]) ; CHECK-NEXT: call void @use(i1 [[C_4]])