mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 15:11:00 +00:00
[ConstraintElimination] Add additional tests.
Adds additional test cases with zexts, conditions that require temporary indices.
This commit is contained in:
parent
be23012d5a
commit
a14a59f2f2
@ -336,6 +336,19 @@ if.end: ; preds = %entry
|
||||
|
||||
|
||||
define i1 @test_n_must_ule_1_due_to_nuw(i8 %n, i8 %i) {
|
||||
; CHECK-LABEL: @test_n_must_ule_1_due_to_nuw(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -1
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1
|
||||
; CHECK-NEXT: ret i1 [[T]]
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1
|
||||
; CHECK-NEXT: ret i1 [[F]]
|
||||
;
|
||||
entry:
|
||||
%sub.n.1 = add nuw i8 %n, -1
|
||||
%add = add nuw i8 %i, %sub.n.1
|
||||
@ -353,6 +366,19 @@ if.end: ; preds = %entry
|
||||
|
||||
|
||||
define i1 @test_n_unknown_missing_nuw(i8 %n, i8 %i) {
|
||||
; CHECK-LABEL: @test_n_unknown_missing_nuw(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -1
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1
|
||||
; CHECK-NEXT: ret i1 [[T]]
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1
|
||||
; CHECK-NEXT: ret i1 [[F]]
|
||||
;
|
||||
entry:
|
||||
%sub.n.1 = add i8 %n, -1
|
||||
%add = add i8 %i, %sub.n.1
|
||||
@ -369,6 +395,19 @@ if.end: ; preds = %entry
|
||||
}
|
||||
|
||||
define i1 @test_n_must_ule_2_due_to_nuw(i8 %n, i8 %i) {
|
||||
; CHECK-LABEL: @test_n_must_ule_2_due_to_nuw(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[SUB_N_1:%.*]] = add nuw i8 [[N:%.*]], -2
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[I:%.*]], [[SUB_N_1]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 2
|
||||
; CHECK-NEXT: ret i1 [[T]]
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 2
|
||||
; CHECK-NEXT: ret i1 [[F]]
|
||||
;
|
||||
entry:
|
||||
%sub.n.1 = add nuw i8 %n, -2
|
||||
%add = add nuw i8 %i, %sub.n.1
|
||||
@ -386,6 +425,19 @@ if.end: ; preds = %entry
|
||||
|
||||
|
||||
define i1 @test_n_unknown_missing_nuw2(i8 %n, i8 %i) {
|
||||
; CHECK-LABEL: @test_n_unknown_missing_nuw2(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[SUB_N_1:%.*]] = add i8 [[N:%.*]], -2
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[I:%.*]], [[SUB_N_1]]
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[I]], [[ADD]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[T:%.*]] = icmp ule i8 [[N]], 1
|
||||
; CHECK-NEXT: ret i1 [[T]]
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[F:%.*]] = icmp ule i8 [[N]], 1
|
||||
; CHECK-NEXT: ret i1 [[F]]
|
||||
;
|
||||
entry:
|
||||
%sub.n.1 = add i8 %n, -2
|
||||
%add = add i8 %i, %sub.n.1
|
||||
|
@ -0,0 +1,73 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -constraint-elimination -S %s | FileCheck %s
|
||||
|
||||
declare void @use(i1)
|
||||
|
||||
|
||||
define void @test_uge_temporary_indices_decompose(i8 %start, i8 %n, i8 %idx) {
|
||||
; CHECK-LABEL: @test_uge_temporary_indices_decompose(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CMP_PRE:%.*]] = icmp ult i8 [[IDX:%.*]], [[N:%.*]]
|
||||
; CHECK-NEXT: [[START_ADD_IDX:%.*]] = add nuw nsw i8 [[START:%.*]], [[IDX]]
|
||||
; CHECK-NEXT: [[START_ADD_N:%.*]] = add nuw nsw i8 [[START]], [[N]]
|
||||
; CHECK-NEXT: [[START_ADD_1:%.*]] = add nuw nsw i8 [[START]], 1
|
||||
; CHECK-NEXT: br i1 [[CMP_PRE]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[T_0:%.*]] = icmp ult i8 [[START_ADD_IDX]], [[START_ADD_N]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_0]])
|
||||
; CHECK-NEXT: [[F_0:%.*]] = icmp uge i8 [[START_ADD_IDX]], [[START_ADD_N]]
|
||||
; CHECK-NEXT: call void @use(i1 [[F_0]])
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[START_ADD_1]], [[START_ADD_N]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ult i8 [[START_ADD_IDX]], [[START_ADD_1]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp ult i8 [[START_ADD_IDX]], [[START_ADD_N]]
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[START_ADD_IDX]], [[START_ADD_N]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp ult i8 [[START_ADD_1]], [[START_ADD_N]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_ADD_IDX]], [[START_ADD_1]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%cmp.pre = icmp ult i8 %idx, %n
|
||||
%start.add.idx = add nuw nsw i8 %start, %idx
|
||||
%start.add.n = add nuw nsw i8 %start, %n
|
||||
%start.add.1 = add nuw nsw i8 %start, 1
|
||||
br i1 %cmp.pre, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%t.0 = icmp ult i8 %start.add.idx, %start.add.n
|
||||
call void @use(i1 %t.0)
|
||||
|
||||
%f.0 = icmp uge i8 %start.add.idx, %start.add.n
|
||||
call void @use(i1 %f.0)
|
||||
|
||||
%c.1 = icmp ult i8 %start.add.1, %start.add.n
|
||||
call void @use(i1 %c.1)
|
||||
|
||||
%c.2 = icmp ult i8 %start.add.idx, %start.add.1
|
||||
call void @use(i1 %c.2)
|
||||
|
||||
ret void
|
||||
|
||||
|
||||
if.end: ; preds = %entry
|
||||
%f.1 = icmp ult i8 %start.add.idx, %start.add.n
|
||||
call void @use(i1 %f.1)
|
||||
|
||||
%t.1 = icmp uge i8 %start.add.idx, %start.add.n
|
||||
call void @use(i1 %t.1)
|
||||
|
||||
%c.3 = icmp ult i8 %start.add.1, %start.add.n
|
||||
call void @use(i1 %c.3)
|
||||
|
||||
%c.4 = icmp ult i8 %start.add.idx, %start.add.1
|
||||
call void @use(i1 %c.4)
|
||||
|
||||
ret void
|
||||
}
|
@ -75,7 +75,7 @@ tgt.bb:
|
||||
ret i1 %cmp1
|
||||
}
|
||||
|
||||
define i4 @ptr_N_signed_positive_explicit_check_constant_step(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
|
||||
define i4 @ptr_N_signed_positive_explicit_check_constant_step(i8* %src, i8* %lower, i8* %upper, i16 %N) {
|
||||
; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
|
||||
@ -131,7 +131,7 @@ exit:
|
||||
}
|
||||
|
||||
; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.
|
||||
define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
|
||||
define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(i8* %src, i8* %lower, i8* %upper, i16 %N) {
|
||||
; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
|
||||
@ -781,3 +781,117 @@ ptr.check:
|
||||
exit:
|
||||
ret i4 3
|
||||
}
|
||||
|
||||
define i4 @ptr_N_step_zext_n_zext(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
|
||||
; CHECK-LABEL: @ptr_N_step_zext_n_zext(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[N_ADD_1:%.*]] = add nuw nsw i16 [[N:%.*]], 1
|
||||
; CHECK-NEXT: [[N_ADD_1_EXT:%.*]] = zext i16 [[N_ADD_1]] to i32
|
||||
; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i32 [[N_ADD_1_EXT]]
|
||||
; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
|
||||
; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
|
||||
; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
|
||||
; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
|
||||
; CHECK: trap.bb:
|
||||
; CHECK-NEXT: ret i4 2
|
||||
; CHECK: step.check:
|
||||
; CHECK-NEXT: [[STEP_ADD_1:%.*]] = add nuw nsw i16 [[STEP:%.*]], 1
|
||||
; CHECK-NEXT: [[STEP_ADD_1_EXT:%.*]] = zext i16 [[STEP_ADD_1]] to i32
|
||||
; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_ADD_1_EXT]], [[N_ADD_1_EXT]]
|
||||
; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
|
||||
; CHECK: ptr.check:
|
||||
; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i32 [[STEP_ADD_1_EXT]]
|
||||
; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
|
||||
; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
|
||||
; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], false
|
||||
; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i4 3
|
||||
;
|
||||
|
||||
entry:
|
||||
%N.add.1 = add nuw nsw i16 %N, 1
|
||||
%N.add.1.ext = zext i16 %N.add.1 to i32
|
||||
%src.end = getelementptr inbounds i8, i8* %src, i32 %N.add.1.ext
|
||||
%cmp.src.start = icmp ult i8* %src, %lower
|
||||
%cmp.src.end = icmp uge i8* %src.end, %upper
|
||||
%or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
|
||||
br i1 %or.precond.0, label %trap.bb, label %step.check
|
||||
|
||||
trap.bb:
|
||||
ret i4 2
|
||||
|
||||
step.check:
|
||||
%step.add.1 = add nuw nsw i16 %step, 1
|
||||
%step.add.1.ext = zext i16 %step.add.1 to i32
|
||||
%step.ult.N = icmp ult i32 %step.add.1.ext, %N.add.1.ext
|
||||
br i1 %step.ult.N, label %ptr.check, label %exit
|
||||
|
||||
ptr.check:
|
||||
%src.step = getelementptr inbounds i8, i8* %src, i32 %step.add.1.ext
|
||||
%cmp.step.start = icmp ult i8* %src.step, %lower
|
||||
%cmp.step.end = icmp uge i8* %src.step, %upper
|
||||
%or.check = or i1 %cmp.step.start, %cmp.step.end
|
||||
br i1 %or.check, label %trap.bb, label %exit
|
||||
|
||||
exit:
|
||||
ret i4 3
|
||||
}
|
||||
|
||||
define i4 @ptr_N_step_zext_n_zext_out_of_bounds(i8* %src, i8* %lower, i8* %upper, i16 %N, i16 %step) {
|
||||
; CHECK-LABEL: @ptr_N_step_zext_n_zext_out_of_bounds(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[N_ADD_2:%.*]] = add nuw nsw i16 [[N:%.*]], 2
|
||||
; CHECK-NEXT: [[N_ADD_2_EXT:%.*]] = zext i16 [[N_ADD_2]] to i32
|
||||
; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i32 [[N_ADD_2_EXT]]
|
||||
; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult i8* [[SRC]], [[LOWER:%.*]]
|
||||
; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge i8* [[SRC_END]], [[UPPER:%.*]]
|
||||
; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
|
||||
; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
|
||||
; CHECK: trap.bb:
|
||||
; CHECK-NEXT: ret i4 2
|
||||
; CHECK: step.check:
|
||||
; CHECK-NEXT: [[STEP_ADD_2:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
|
||||
; CHECK-NEXT: [[STEP_ADD_2_EXT:%.*]] = zext i16 [[STEP_ADD_2]] to i32
|
||||
; CHECK-NEXT: [[STEP_EXT:%.*]] = zext i16 [[STEP]] to i32
|
||||
; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_EXT]], [[N_ADD_2_EXT]]
|
||||
; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
|
||||
; CHECK: ptr.check:
|
||||
; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i32 [[STEP_ADD_2_EXT]]
|
||||
; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
|
||||
; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
|
||||
; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
|
||||
; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i4 3
|
||||
;
|
||||
|
||||
entry:
|
||||
%N.add.2 = add nuw nsw i16 %N, 2
|
||||
%N.add.2.ext = zext i16 %N.add.2 to i32
|
||||
%src.end = getelementptr inbounds i8, i8* %src, i32 %N.add.2.ext
|
||||
%cmp.src.start = icmp ult i8* %src, %lower
|
||||
%cmp.src.end = icmp uge i8* %src.end, %upper
|
||||
%or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
|
||||
br i1 %or.precond.0, label %trap.bb, label %step.check
|
||||
|
||||
trap.bb:
|
||||
ret i4 2
|
||||
|
||||
step.check:
|
||||
%step.add.2 = add nuw nsw i16 %step, 2
|
||||
%step.add.2.ext = zext i16 %step.add.2 to i32
|
||||
%step.ext = zext i16 %step to i32
|
||||
%step.ult.N = icmp ult i32 %step.ext, %N.add.2.ext
|
||||
br i1 %step.ult.N, label %ptr.check, label %exit
|
||||
|
||||
ptr.check:
|
||||
%src.step = getelementptr inbounds i8, i8* %src, i32 %step.add.2.ext
|
||||
%cmp.step.start = icmp ult i8* %src.step, %lower
|
||||
%cmp.step.end = icmp uge i8* %src.step, %upper
|
||||
%or.check = or i1 %cmp.step.start, %cmp.step.end
|
||||
br i1 %or.check, label %trap.bb, label %exit
|
||||
|
||||
exit:
|
||||
ret i4 3
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ define void @test_ptr_need_one_upper_check(i32* readonly %src, i32* %dst, i32 %n
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_CHECK_1:%.*]], label [[EXIT:%.*]]
|
||||
; CHECK: loop.check.1:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64
|
||||
; CHECK-NEXT: [[SRC_UPPER:%.*]] = getelementptr i32, i32* [[SRC:%.*]], i64 [[TMP0]]
|
||||
; CHECK-NEXT: [[SRC_UPPER:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i64 [[TMP0]]
|
||||
; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[I_0]], 2
|
||||
; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[ADD]] to i64
|
||||
; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[IDXPROM]]
|
||||
@ -660,7 +660,7 @@ define void @test_ptr_need_one_upper_check(i32* readonly %src, i32* %dst, i32 %n
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP_SRC_IDX_UPPER]])
|
||||
; CHECK-NEXT: br i1 [[CMP_SRC_IDX_UPPER]], label [[LOOP_LATCH:%.*]], label [[EXIT]]
|
||||
; CHECK: loop.latch:
|
||||
; CHECK-NEXT: [[DST_UPPER:%.*]] = getelementptr i32, i32* [[DST:%.*]], i64 [[TMP0]]
|
||||
; CHECK-NEXT: [[DST_UPPER:%.*]] = getelementptr inbounds i32, i32* [[DST:%.*]], i64 [[TMP0]]
|
||||
; CHECK-NEXT: [[DST_IDX:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 [[IDXPROM]]
|
||||
; CHECK-NEXT: [[CMP_DST_IDX_UPPER:%.*]] = icmp ult i32* [[DST_IDX]], [[DST_UPPER]]
|
||||
; CHECK-NEXT: call void @use(i1 [[CMP_DST_IDX_UPPER]])
|
||||
@ -680,7 +680,7 @@ loop.header:
|
||||
|
||||
loop.check.1:
|
||||
%0 = zext i32 %n to i64
|
||||
%src.upper = getelementptr i32, i32* %src, i64 %0
|
||||
%src.upper = getelementptr inbounds i32, i32* %src, i64 %0
|
||||
%add = add nuw nsw i32 %i.0, 2
|
||||
%idxprom = zext i32 %add to i64
|
||||
%src.idx = getelementptr inbounds i32, i32* %src, i64 %idxprom
|
||||
@ -689,7 +689,7 @@ loop.check.1:
|
||||
br i1 %cmp.src.idx.upper, label %loop.latch, label %exit
|
||||
|
||||
loop.latch:
|
||||
%dst.upper = getelementptr i32, i32* %dst, i64 %0
|
||||
%dst.upper = getelementptr inbounds i32, i32* %dst, i64 %0
|
||||
%dst.idx = getelementptr inbounds i32, i32* %dst, i64 %idxprom
|
||||
%cmp.dst.idx.upper = icmp ult i32* %dst.idx, %dst.upper
|
||||
call void @use(i1 %cmp.dst.idx.upper)
|
||||
|
289
llvm/test/Transforms/ConstraintElimination/zext.ll
Normal file
289
llvm/test/Transforms/ConstraintElimination/zext.ll
Normal file
@ -0,0 +1,289 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -constraint-elimination -S %s | FileCheck %s
|
||||
|
||||
declare void @use(i1)
|
||||
|
||||
define void @uge_zext(i16 %x, i32 %y) {
|
||||
; CHECK-LABEL: @uge_zext(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X_EXT:%.*]] = zext i16 [[X:%.*]] to i32
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y:%.*]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y]]
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i32 [[Y]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[C_4:%.*]] = icmp uge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp uge i32 [[Y]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 true)
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y]]
|
||||
; CHECK-NEXT: call void @use(i1 false)
|
||||
; CHECK-NEXT: [[C_5:%.*]] = icmp uge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||
; CHECK-NEXT: [[C_6:%.*]] = icmp uge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_6]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%x.ext = zext i16 %x to i32
|
||||
%c.1 = icmp uge i32 %x.ext, %y
|
||||
br i1 %c.1, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
%t.1 = icmp uge i32 %x.ext, %y
|
||||
call void @use(i1 %t.1)
|
||||
%c.2 = icmp uge i32 %x.ext, 10
|
||||
call void @use(i1 %c.2)
|
||||
%c.3 = icmp uge i32 %y, %x.ext
|
||||
call void @use(i1 %c.3)
|
||||
%c.4 = icmp uge i32 10, %x.ext
|
||||
call void @use(i1 %c.4)
|
||||
ret void
|
||||
|
||||
bb2:
|
||||
%t.2 = icmp uge i32 %y, %x.ext
|
||||
call void @use(i1 %t.2)
|
||||
%f.1 = icmp uge i32 %x.ext, %y
|
||||
call void @use(i1 %f.1)
|
||||
%c.5 = icmp uge i32 %x.ext, 10
|
||||
call void @use(i1 %c.5)
|
||||
%c.6 = icmp uge i32 10, %x.ext
|
||||
call void @use(i1 %c.6)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @uge_compare_short_and_extended(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: @uge_compare_short_and_extended(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i16 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[X_EXT:%.*]] = zext i16 [[X]] to i32
|
||||
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i16 [[Y]] to i32
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i32 [[Y_EXT]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[C_4:%.*]] = icmp uge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp uge i32 [[Y_EXT]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[C_5:%.*]] = icmp uge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||
; CHECK-NEXT: [[C_6:%.*]] = icmp uge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_6]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%c.1 = icmp uge i16 %x, %y
|
||||
%x.ext = zext i16 %x to i32
|
||||
%y.ext = zext i16 %y to i32
|
||||
br i1 %c.1, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
%t.1 = icmp uge i32 %x.ext, %y.ext
|
||||
call void @use(i1 %t.1)
|
||||
%c.2 = icmp uge i32 %x.ext, 10
|
||||
call void @use(i1 %c.2)
|
||||
%c.3 = icmp sge i32 %y.ext, %x.ext
|
||||
call void @use(i1 %c.3)
|
||||
%c.4 = icmp uge i32 10, %x.ext
|
||||
call void @use(i1 %c.4)
|
||||
ret void
|
||||
|
||||
bb2:
|
||||
%t.2 = icmp uge i32 %y.ext, %x.ext
|
||||
call void @use(i1 %t.2)
|
||||
%f.1 = icmp uge i32 %x.ext, %y.ext
|
||||
call void @use(i1 %f.1)
|
||||
%c.5 = icmp uge i32 %x.ext, 10
|
||||
call void @use(i1 %c.5)
|
||||
%c.6 = icmp uge i32 10, %x.ext
|
||||
call void @use(i1 %c.6)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @uge_zext_add(i16 %x, i32 %y) {
|
||||
; CHECK-LABEL: @uge_zext_add(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X_ADD_1:%.*]] = add nuw nsw i16 [[X:%.*]], 1
|
||||
; CHECK-NEXT: [[X_ADD_1_EXT:%.*]] = zext i16 [[X_ADD_1]] to i32
|
||||
; CHECK-NEXT: [[X_EXT:%.*]] = zext i16 [[X]] to i32
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i32 [[X_ADD_1_EXT]], [[Y:%.*]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp uge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp uge i32 [[Y]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[C_4:%.*]] = icmp uge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp uge i32 [[Y]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp uge i32 [[X_EXT]], [[Y]]
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[C_5:%.*]] = icmp uge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||
; CHECK-NEXT: [[C_6:%.*]] = icmp uge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_6]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%x.add.1 = add nuw nsw i16 %x, 1
|
||||
%x.add.1.ext = zext i16 %x.add.1 to i32
|
||||
%x.ext = zext i16 %x to i32
|
||||
%c.1 = icmp uge i32 %x.add.1.ext, %y
|
||||
br i1 %c.1, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
%t.1 = icmp uge i32 %x.ext, %y
|
||||
call void @use(i1 %t.1)
|
||||
%c.2 = icmp uge i32 %x.ext, 10
|
||||
call void @use(i1 %c.2)
|
||||
%c.3 = icmp uge i32 %y, %x.ext
|
||||
call void @use(i1 %c.3)
|
||||
%c.4 = icmp uge i32 10, %x.ext
|
||||
call void @use(i1 %c.4)
|
||||
ret void
|
||||
|
||||
bb2:
|
||||
%t.2 = icmp uge i32 %y, %x.ext
|
||||
call void @use(i1 %t.2)
|
||||
%f.1 = icmp uge i32 %x.ext, %y
|
||||
call void @use(i1 %f.1)
|
||||
%c.5 = icmp uge i32 %x.ext, 10
|
||||
call void @use(i1 %c.5)
|
||||
%c.6 = icmp uge i32 10, %x.ext
|
||||
call void @use(i1 %c.6)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @sge_zext(i16 %x, i32 %y) {
|
||||
; CHECK-LABEL: @sge_zext(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X_EXT:%.*]] = zext i16 [[X:%.*]] to i32
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[X_EXT]], [[Y:%.*]]
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp sge i32 [[X_EXT]], [[Y]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp sge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i32 [[Y]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[Y]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp sge i32 [[X_EXT]], [[Y]]
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||
; CHECK-NEXT: [[C_6:%.*]] = icmp sge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_6]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%x.ext = zext i16 %x to i32
|
||||
%c.1 = icmp sge i32 %x.ext, %y
|
||||
br i1 %c.1, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
%t.1 = icmp sge i32 %x.ext, %y
|
||||
call void @use(i1 %t.1)
|
||||
%c.2 = icmp sge i32 %x.ext, 10
|
||||
call void @use(i1 %c.2)
|
||||
%c.3 = icmp sge i32 %y, %x.ext
|
||||
call void @use(i1 %c.3)
|
||||
%c.4 = icmp sge i32 10, %x.ext
|
||||
call void @use(i1 %c.4)
|
||||
ret void
|
||||
|
||||
bb2:
|
||||
%t.2 = icmp sge i32 %y, %x.ext
|
||||
call void @use(i1 %t.2)
|
||||
%f.1 = icmp sge i32 %x.ext, %y
|
||||
call void @use(i1 %f.1)
|
||||
%c.5 = icmp sge i32 %x.ext, 10
|
||||
call void @use(i1 %c.5)
|
||||
%c.6 = icmp sge i32 10, %x.ext
|
||||
call void @use(i1 %c.6)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
define void @sge_compare_short_and_extended(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: @sge_compare_short_and_extended(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp sge i16 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[X_EXT:%.*]] = zext i16 [[X]] to i32
|
||||
; CHECK-NEXT: [[Y_EXT:%.*]] = zext i16 [[Y]] to i32
|
||||
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||
; CHECK: bb1:
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp sge i32 [[X_EXT]], [[Y_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp sge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp sge i32 [[Y_EXT]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[C_4:%.*]] = icmp sge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_4]])
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: bb2:
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp sge i32 [[Y_EXT]], [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
||||
; CHECK-NEXT: [[F_1:%.*]] = icmp sge i32 [[X_EXT]], [[Y_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
||||
; CHECK-NEXT: [[C_5:%.*]] = icmp sge i32 [[X_EXT]], 10
|
||||
; CHECK-NEXT: call void @use(i1 [[C_5]])
|
||||
; CHECK-NEXT: [[C_6:%.*]] = icmp sge i32 10, [[X_EXT]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_6]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%c.1 = icmp sge i16 %x, %y
|
||||
%x.ext = zext i16 %x to i32
|
||||
%y.ext = zext i16 %y to i32
|
||||
br i1 %c.1, label %bb1, label %bb2
|
||||
|
||||
bb1:
|
||||
%t.1 = icmp sge i32 %x.ext, %y.ext
|
||||
call void @use(i1 %t.1)
|
||||
%c.2 = icmp sge i32 %x.ext, 10
|
||||
call void @use(i1 %c.2)
|
||||
%c.3 = icmp sge i32 %y.ext, %x.ext
|
||||
call void @use(i1 %c.3)
|
||||
%c.4 = icmp sge i32 10, %x.ext
|
||||
call void @use(i1 %c.4)
|
||||
ret void
|
||||
|
||||
bb2:
|
||||
%t.2 = icmp sge i32 %y.ext, %x.ext
|
||||
call void @use(i1 %t.2)
|
||||
%f.1 = icmp sge i32 %x.ext, %y.ext
|
||||
call void @use(i1 %f.1)
|
||||
%c.5 = icmp sge i32 %x.ext, 10
|
||||
call void @use(i1 %c.5)
|
||||
%c.6 = icmp sge i32 10, %x.ext
|
||||
call void @use(i1 %c.6)
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user