forked from OSchip/llvm-project
[instcombine] Avoid binops for comparison consistency tests
It turns out that instcombine is smarter than I am, and several of these ended up folded for the wrong reasons.
This commit is contained in:
parent
b661470bce
commit
a9861d3c85
|
@ -153,26 +153,28 @@ define i1 @offset_single_cmp() {
|
|||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold1() {
|
||||
declare void @witness(i1, i1)
|
||||
|
||||
define void @neg_consistent_fold1() {
|
||||
; CHECK-LABEL: @neg_consistent_fold1(
|
||||
; CHECK-NEXT: [[M1:%.*]] = alloca [4 x i8], align 1
|
||||
; CHECK-NEXT: [[M1_SUB:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[M1]], i32 0, i32 0
|
||||
; CHECK-NEXT: [[RHS2:%.*]] = call i8* @hidden_inttoptr()
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[M1_SUB]], inttoptr (i64 2048 to i8*)
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8* [[M1_SUB]], [[RHS2]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = or i1 [[CMP1]], [[CMP2]]
|
||||
; CHECK-NEXT: ret i1 [[RES]]
|
||||
; CHECK-NEXT: call void @witness(i1 [[CMP1]], i1 [[CMP2]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = alloca i8, i32 4
|
||||
%rhs = inttoptr i64 2048 to i8*
|
||||
%rhs2 = call i8* @hidden_inttoptr()
|
||||
%cmp1 = icmp eq i8* %m, %rhs
|
||||
%cmp2 = icmp eq i8* %m, %rhs2
|
||||
%res = or i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold2() {
|
||||
define void @neg_consistent_fold2() {
|
||||
; CHECK-LABEL: @neg_consistent_fold2(
|
||||
; CHECK-NEXT: [[M1:%.*]] = alloca [4 x i8], align 1
|
||||
; CHECK-NEXT: [[N2:%.*]] = alloca [4 x i8], align 1
|
||||
|
@ -182,8 +184,8 @@ define i1 @neg_consistent_fold2() {
|
|||
; CHECK-NEXT: [[RHS2:%.*]] = call i8* @hidden_offset(i8* nonnull [[N2_SUB]])
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[M1_SUB]], [[RHS]]
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8* [[M1_SUB]], [[RHS2]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = or i1 [[CMP1]], [[CMP2]]
|
||||
; CHECK-NEXT: ret i1 [[RES]]
|
||||
; CHECK-NEXT: call void @witness(i1 [[CMP1]], i1 [[CMP2]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = alloca i8, i32 4
|
||||
%n = alloca i8, i32 4
|
||||
|
@ -191,11 +193,11 @@ define i1 @neg_consistent_fold2() {
|
|||
%rhs2 = call i8* @hidden_offset(i8* %n)
|
||||
%cmp1 = icmp eq i8* %m, %rhs
|
||||
%cmp2 = icmp eq i8* %m, %rhs2
|
||||
%res = or i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold3() {
|
||||
define void @neg_consistent_fold3() {
|
||||
; CHECK-LABEL: @neg_consistent_fold3(
|
||||
; CHECK-NEXT: [[M1:%.*]] = alloca i32, align 1
|
||||
; CHECK-NEXT: [[M1_SUB:%.*]] = bitcast i32* [[M1]] to i8*
|
||||
|
@ -203,8 +205,8 @@ define i1 @neg_consistent_fold3() {
|
|||
; CHECK-NEXT: [[RHS2:%.*]] = call i8* @hidden_inttoptr()
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32* [[M1]], [[LGP]]
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8* [[RHS2]], [[M1_SUB]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = or i1 [[CMP1]], [[CMP2]]
|
||||
; CHECK-NEXT: ret i1 [[RES]]
|
||||
; CHECK-NEXT: call void @witness(i1 [[CMP1]], i1 [[CMP2]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = alloca i8, i32 4
|
||||
%bc = bitcast i8* %m to i32*
|
||||
|
@ -212,21 +214,22 @@ define i1 @neg_consistent_fold3() {
|
|||
%rhs2 = call i8* @hidden_inttoptr()
|
||||
%cmp1 = icmp eq i32* %bc, %lgp
|
||||
%cmp2 = icmp eq i8* %m, %rhs2
|
||||
%res = or i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold4() {
|
||||
define void @neg_consistent_fold4() {
|
||||
; CHECK-LABEL: @neg_consistent_fold4(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
; CHECK-NEXT: call void @witness(i1 false, i1 false)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = alloca i8, i32 4
|
||||
%bc = bitcast i8* %m to i32*
|
||||
%lgp = load i32*, i32** @gp, align 8
|
||||
%cmp1 = icmp eq i32* %bc, %lgp
|
||||
%cmp2 = icmp eq i32* %bc, %lgp
|
||||
%res = or i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; A nocapture call can't cause a consistent result issue as it is (by
|
||||
|
|
|
@ -240,25 +240,27 @@ define i1 @offset_single_cmp() {
|
|||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold1() {
|
||||
declare void @witness(i1, i1)
|
||||
|
||||
define void @neg_consistent_fold1() {
|
||||
; CHECK-LABEL: @neg_consistent_fold1(
|
||||
; CHECK-NEXT: [[M:%.*]] = call dereferenceable_or_null(4) i8* @malloc(i64 4)
|
||||
; CHECK-NEXT: [[RHS2:%.*]] = call i8* @hidden_inttoptr()
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[M]], inttoptr (i64 2048 to i8*)
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[RHS2]], inttoptr (i64 2048 to i8*)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[CMP1]], [[TMP1]]
|
||||
; CHECK-NEXT: ret i1 [[TMP2]]
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8* [[M]], [[RHS2]]
|
||||
; CHECK-NEXT: call void @witness(i1 [[CMP1]], i1 [[CMP2]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = call i8* @malloc(i64 4)
|
||||
%rhs = inttoptr i64 2048 to i8*
|
||||
%rhs2 = call i8* @hidden_inttoptr()
|
||||
%cmp1 = icmp eq i8* %m, %rhs
|
||||
%cmp2 = icmp eq i8* %m, %rhs2
|
||||
%res = and i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold2() {
|
||||
define void @neg_consistent_fold2() {
|
||||
; CHECK-LABEL: @neg_consistent_fold2(
|
||||
; CHECK-NEXT: [[M:%.*]] = call dereferenceable_or_null(4) i8* @malloc(i64 4)
|
||||
; CHECK-NEXT: [[N:%.*]] = call dereferenceable_or_null(4) i8* @malloc(i64 4)
|
||||
|
@ -266,8 +268,8 @@ define i1 @neg_consistent_fold2() {
|
|||
; CHECK-NEXT: [[RHS2:%.*]] = call i8* @hidden_offset(i8* [[N]])
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[M]], [[RHS]]
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8* [[M]], [[RHS2]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = and i1 [[CMP1]], [[CMP2]]
|
||||
; CHECK-NEXT: ret i1 [[RES]]
|
||||
; CHECK-NEXT: call void @witness(i1 [[CMP1]], i1 [[CMP2]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = call i8* @malloc(i64 4)
|
||||
%n = call i8* @malloc(i64 4)
|
||||
|
@ -275,11 +277,11 @@ define i1 @neg_consistent_fold2() {
|
|||
%rhs2 = call i8* @hidden_offset(i8* %n)
|
||||
%cmp1 = icmp eq i8* %m, %rhs
|
||||
%cmp2 = icmp eq i8* %m, %rhs2
|
||||
%res = and i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @neg_consistent_fold3() {
|
||||
define void @neg_consistent_fold3() {
|
||||
; CHECK-LABEL: @neg_consistent_fold3(
|
||||
; CHECK-NEXT: [[M:%.*]] = call dereferenceable_or_null(4) i8* @malloc(i64 4)
|
||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[M]] to i32*
|
||||
|
@ -287,8 +289,8 @@ define i1 @neg_consistent_fold3() {
|
|||
; CHECK-NEXT: [[RHS2:%.*]] = call i8* @hidden_inttoptr()
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32* [[LGP]], [[BC]]
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8* [[M]], [[RHS2]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = and i1 [[CMP1]], [[CMP2]]
|
||||
; CHECK-NEXT: ret i1 [[RES]]
|
||||
; CHECK-NEXT: call void @witness(i1 [[CMP1]], i1 [[CMP2]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = call i8* @malloc(i64 4)
|
||||
%bc = bitcast i8* %m to i32*
|
||||
|
@ -296,24 +298,25 @@ define i1 @neg_consistent_fold3() {
|
|||
%rhs2 = call i8* @hidden_inttoptr()
|
||||
%cmp1 = icmp eq i32* %bc, %lgp
|
||||
%cmp2 = icmp eq i8* %m, %rhs2
|
||||
%res = and i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; FIXME: This appears correct, but the current implementation relies
|
||||
; on visiting both cmps in the same pass. We may have an simplification order
|
||||
; under which one is missed, and that would be a bug.
|
||||
define i1 @neg_consistent_fold4() {
|
||||
define void @neg_consistent_fold4() {
|
||||
; CHECK-LABEL: @neg_consistent_fold4(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
; CHECK-NEXT: call void @witness(i1 false, i1 false)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%m = call i8* @malloc(i64 4)
|
||||
%bc = bitcast i8* %m to i32*
|
||||
%lgp = load i32*, i32** @gp, align 8
|
||||
%cmp1 = icmp eq i32* %bc, %lgp
|
||||
%cmp2 = icmp eq i32* %bc, %lgp
|
||||
%res = and i1 %cmp1, %cmp2
|
||||
ret i1 %res
|
||||
call void @witness(i1 %cmp1, i1 %cmp2)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @unknown(i8*)
|
||||
|
|
Loading…
Reference in New Issue