forked from OSchip/llvm-project
[InstCombine] auto-generate better checks; NFC
Also, move a test next to its sibling to eliminate a file with just one test. llvm-svn: 299824
This commit is contained in:
parent
a9d67cf601
commit
c5f963c2e5
|
@ -3,238 +3,291 @@
|
|||
declare double @llvm.fabs.f64(double) nounwind readnone
|
||||
|
||||
define i1 @test1(float %x, float %y) nounwind {
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %x, %y
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%ext1 = fpext float %x to double
|
||||
%ext2 = fpext float %y to double
|
||||
%cmp = fcmp ogt double %ext1, %ext2
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: fcmp ogt float %x, %y
|
||||
}
|
||||
|
||||
define i1 @test2(float %a) nounwind {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %a, 1.000000e+00
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%ext = fpext float %a to double
|
||||
%cmp = fcmp ogt double %ext, 1.000000e+00
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: fcmp ogt float %a, 1.0
|
||||
}
|
||||
|
||||
define i1 @test3(float %a) nounwind {
|
||||
; CHECK-LABEL: @test3(
|
||||
; CHECK-NEXT: [[EXT:%.*]] = fpext float %a to double
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x3FF0000000000001
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%ext = fpext float %a to double
|
||||
%cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test3(
|
||||
; CHECK-NEXT: fpext float %a to double
|
||||
}
|
||||
|
||||
define i1 @test4(float %a) nounwind {
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK-NEXT: [[EXT:%.*]] = fpext float %a to double
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[EXT]], 0x36A0000000000000
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%ext = fpext float %a to double
|
||||
%cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK-NEXT: fpext float %a to double
|
||||
}
|
||||
|
||||
define i1 @test5(float %a) nounwind {
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float %a, -1.000000e+00
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%neg = fsub float -0.000000e+00, %a
|
||||
%cmp = fcmp ogt float %neg, 1.000000e+00
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK-NEXT: fcmp olt float %a, -1.0
|
||||
}
|
||||
|
||||
define i1 @test6(float %x, float %y) nounwind {
|
||||
; CHECK-LABEL: @test6(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %x, %y
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%neg1 = fsub float -0.000000e+00, %x
|
||||
%neg2 = fsub float -0.000000e+00, %y
|
||||
%cmp = fcmp olt float %neg1, %neg2
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test6(
|
||||
; CHECK-NEXT: fcmp ogt float %x, %y
|
||||
}
|
||||
|
||||
define i1 @test7(float %x) nounwind readnone ssp noredzone {
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float %x, 0.000000e+00
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%ext = fpext float %x to ppc_fp128
|
||||
%cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000
|
||||
ret i1 %cmp
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK-NEXT: fcmp ogt float %x, 0.000000e+00
|
||||
}
|
||||
|
||||
define float @test8(float %x) nounwind readnone optsize ssp {
|
||||
; CHECK-LABEL: @test8(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float %x, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV2:%.*]] = uitofp i1 [[CMP]] to float
|
||||
; CHECK-NEXT: ret float [[CONV2]]
|
||||
;
|
||||
%conv = fpext float %x to double
|
||||
%cmp = fcmp olt double %conv, 0.000000e+00
|
||||
%conv1 = zext i1 %cmp to i32
|
||||
%conv2 = sitofp i32 %conv1 to float
|
||||
ret float %conv2
|
||||
; Float comparison to zero shouldn't cast to double.
|
||||
; CHECK-LABEL: @test8(
|
||||
; CHECK-NEXT: fcmp olt float %x, 0.000000e+00
|
||||
}
|
||||
|
||||
declare double @fabs(double) nounwind readnone
|
||||
|
||||
define i32 @test9(double %a) nounwind {
|
||||
; CHECK-LABEL: @test9(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp olt double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test9(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
define i32 @test9_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test9_intrinsic(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp olt double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test9_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
define i32 @test10(double %a) nounwind {
|
||||
; CHECK-LABEL: @test10(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp ole double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test10(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp oeq double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test10_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test10_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp ole double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test10_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp oeq double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test11(double %a) nounwind {
|
||||
; CHECK-LABEL: @test11(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp ogt double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test11(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp one double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test11_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test11_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp ogt double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test11_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp one double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test12(double %a) nounwind {
|
||||
; CHECK-LABEL: @test12(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp oge double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test12(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp ord double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test12_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test12_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ord double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp oge double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test12_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp ord double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test13(double %a) nounwind {
|
||||
; CHECK-LABEL: @test13(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp une double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test13(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp une double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test13_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test13_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp une double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test13_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp une double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test14(double %a) nounwind {
|
||||
; CHECK-LABEL: @test14(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp oeq double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test14(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp oeq double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test14_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test14_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp oeq double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test14_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp oeq double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test15(double %a) nounwind {
|
||||
; CHECK-LABEL: @test15(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp one double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test15(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp one double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test15_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test15_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp one double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp one double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test15_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp one double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test16(double %a) nounwind {
|
||||
; CHECK-LABEL: @test16(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @fabs(double %a) nounwind
|
||||
%cmp = fcmp ueq double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test16(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp ueq double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
define i32 @test16_intrinsic(double %a) nounwind {
|
||||
; CHECK-LABEL: @test16_intrinsic(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double %a, 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double @llvm.fabs.f64(double %a) nounwind
|
||||
%cmp = fcmp ueq double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
; CHECK-LABEL: @test16_intrinsic(
|
||||
; CHECK-NOT: fabs
|
||||
; CHECK: fcmp ueq double %a, 0.000000e+00
|
||||
}
|
||||
|
||||
; Don't crash.
|
||||
define i32 @test17(double %a, double (double)* %p) nounwind {
|
||||
; CHECK-LABEL: @test17(
|
||||
; CHECK-NEXT: [[CALL:%.*]] = tail call double %p(double %a) #1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[CALL]], 0.000000e+00
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
%call = tail call double %p(double %a) nounwind
|
||||
%cmp = fcmp ueq double %call, 0.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
|
@ -243,16 +296,18 @@ define i32 @test17(double %a, double (double)* %p) nounwind {
|
|||
|
||||
; Can fold fcmp with undef on one side by choosing NaN for the undef
|
||||
define i32 @test18_undef_unordered(float %a) nounwind {
|
||||
; CHECK-LABEL: @test18_undef_unordered
|
||||
; CHECK: ret i32 1
|
||||
; CHECK-LABEL: @test18_undef_unordered(
|
||||
; CHECK-NEXT: ret i32 1
|
||||
;
|
||||
%cmp = fcmp ueq float %a, undef
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
; Can fold fcmp with undef on one side by choosing NaN for the undef
|
||||
define i32 @test18_undef_ordered(float %a) nounwind {
|
||||
; CHECK-LABEL: @test18_undef_ordered
|
||||
; CHECK: ret i32 0
|
||||
; CHECK-LABEL: @test18_undef_ordered(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%cmp = fcmp oeq float %a, undef
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
|
@ -264,14 +319,30 @@ define i32 @test18_undef_ordered(float %a) nounwind {
|
|||
; because whatever you choose for the first undef
|
||||
; you can choose NaN for the other undef
|
||||
define i1 @test19_undef_unordered() nounwind {
|
||||
; CHECK-LABEL: @test19_undef
|
||||
; CHECK: ret i1 true
|
||||
; CHECK-LABEL: @test19_undef_unordered(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
;
|
||||
%cmp = fcmp ueq float undef, undef
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
define i1 @test19_undef_ordered() nounwind {
|
||||
; CHECK-LABEL: @test19_undef
|
||||
; CHECK: ret i1 false
|
||||
; CHECK-LABEL: @test19_undef_ordered(
|
||||
; CHECK-NEXT: ret i1 false
|
||||
;
|
||||
%cmp = fcmp oeq float undef, undef
|
||||
ret i1 %cmp
|
||||
}
|
||||
|
||||
; PR1570
|
||||
|
||||
define i1 @invert_fcmp(float %X, float %Y) {
|
||||
; CHECK-LABEL: @invert_fcmp(
|
||||
; CHECK-NEXT: [[TOBOOLNOT5:%.*]] = fcmp uge float %X, %Y
|
||||
; CHECK-NEXT: ret i1 [[TOBOOLNOT5]]
|
||||
;
|
||||
%tmp3 = fcmp olt float %X, %Y
|
||||
%toBoolnot5 = xor i1 %tmp3, true
|
||||
ret i1 %toBoolnot5
|
||||
}
|
||||
|
||||
|
|
|
@ -14,67 +14,76 @@ declare i32 @memcmp(i8*, i8*, i32)
|
|||
|
||||
define i32 @test_simplify1(i8* %mem, i32 %size) {
|
||||
; CHECK-LABEL: @test_simplify1(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%ret = call i32 @memcmp(i8* %mem, i8* %mem, i32 %size)
|
||||
ret i32 %ret
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
; Check memcmp(mem1, mem2, 0) -> 0.
|
||||
|
||||
define i32 @test_simplify2(i8* %mem1, i8* %mem2) {
|
||||
; CHECK-LABEL: @test_simplify2(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 0)
|
||||
ret i32 %ret
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
;; Check memcmp(mem1, mem2, 1) -> *(unsigned char*)mem1 - *(unsigned char*)mem2.
|
||||
|
||||
define i32 @test_simplify3(i8* %mem1, i8* %mem2) {
|
||||
; CHECK-LABEL: @test_simplify3(
|
||||
; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* %mem1, align 1
|
||||
; CHECK-NEXT: [[LHSV:%.*]] = zext i8 [[LHSC]] to i32
|
||||
; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* %mem2, align 1
|
||||
; CHECK-NEXT: [[RHSV:%.*]] = zext i8 [[RHSC]] to i32
|
||||
; CHECK-NEXT: [[CHARDIFF:%.*]] = sub nsw i32 [[LHSV]], [[RHSV]]
|
||||
; CHECK-NEXT: ret i32 [[CHARDIFF]]
|
||||
;
|
||||
%ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 1)
|
||||
; CHECK: [[LOAD1:%[a-z]+]] = load i8, i8* %mem1, align 1
|
||||
; CHECK: [[ZEXT1:%[a-z]+]] = zext i8 [[LOAD1]] to i32
|
||||
; CHECK: [[LOAD2:%[a-z]+]] = load i8, i8* %mem2, align 1
|
||||
; CHECK: [[ZEXT2:%[a-z]+]] = zext i8 [[LOAD2]] to i32
|
||||
; CHECK: [[RET:%[a-z]+]] = sub nsw i32 [[ZEXT1]], [[ZEXT2]]
|
||||
ret i32 %ret
|
||||
; CHECK: ret i32 [[RET]]
|
||||
}
|
||||
|
||||
; Check memcmp(mem1, mem2, size) -> cnst, where all arguments are constants.
|
||||
|
||||
define i32 @test_simplify4() {
|
||||
; CHECK-LABEL: @test_simplify4(
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%mem1 = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0
|
||||
%mem2 = getelementptr [8 x i8], [8 x i8]* @hello_u, i32 0, i32 0
|
||||
%ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3)
|
||||
ret i32 %ret
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
define i32 @test_simplify5() {
|
||||
; CHECK-LABEL: @test_simplify5(
|
||||
; CHECK-NEXT: ret i32 1
|
||||
;
|
||||
%mem1 = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0
|
||||
%mem2 = getelementptr [4 x i8], [4 x i8]* @foo, i32 0, i32 0
|
||||
%ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3)
|
||||
ret i32 %ret
|
||||
; CHECK: ret i32 1
|
||||
}
|
||||
|
||||
define i32 @test_simplify6() {
|
||||
; CHECK-LABEL: @test_simplify6(
|
||||
; CHECK-NEXT: ret i32 -1
|
||||
;
|
||||
%mem1 = getelementptr [4 x i8], [4 x i8]* @foo, i32 0, i32 0
|
||||
%mem2 = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0
|
||||
%ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3)
|
||||
ret i32 %ret
|
||||
; CHECK: ret i32 -1
|
||||
}
|
||||
|
||||
; Check memcmp(mem1, mem2, 8)==0 -> *(int64_t*)mem1 == *(int64_t*)mem2
|
||||
|
||||
define i1 @test_simplify7(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: @test_simplify7(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 %x, %y
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%x.addr = alloca i64, align 8
|
||||
%y.addr = alloca i64, align 8
|
||||
store i64 %x, i64* %x.addr, align 8
|
||||
|
@ -84,14 +93,15 @@ define i1 @test_simplify7(i64 %x, i64 %y) {
|
|||
%call = call i32 @memcmp(i8* %xptr, i8* %yptr, i32 8)
|
||||
%cmp = icmp eq i32 %call, 0
|
||||
ret i1 %cmp
|
||||
; CHECK: %cmp = icmp eq i64 %x, %y
|
||||
; CHECK: ret i1 %cmp
|
||||
}
|
||||
|
||||
; Check memcmp(mem1, mem2, 4)==0 -> *(int32_t*)mem1 == *(int32_t*)mem2
|
||||
|
||||
define i1 @test_simplify8(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test_simplify8(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %x, %y
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%x.addr = alloca i32, align 4
|
||||
%y.addr = alloca i32, align 4
|
||||
store i32 %x, i32* %x.addr, align 4
|
||||
|
@ -101,14 +111,15 @@ define i1 @test_simplify8(i32 %x, i32 %y) {
|
|||
%call = call i32 @memcmp(i8* %xptr, i8* %yptr, i32 4)
|
||||
%cmp = icmp eq i32 %call, 0
|
||||
ret i1 %cmp
|
||||
; CHECK: %cmp = icmp eq i32 %x, %y
|
||||
; CHECK: ret i1 %cmp
|
||||
}
|
||||
|
||||
; Check memcmp(mem1, mem2, 2)==0 -> *(int16_t*)mem1 == *(int16_t*)mem2
|
||||
|
||||
define i1 @test_simplify9(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: @test_simplify9(
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 %x, %y
|
||||
; CHECK-NEXT: ret i1 [[CMP]]
|
||||
;
|
||||
%x.addr = alloca i16, align 2
|
||||
%y.addr = alloca i16, align 2
|
||||
store i16 %x, i16* %x.addr, align 2
|
||||
|
@ -118,6 +129,4 @@ define i1 @test_simplify9(i16 %x, i16 %y) {
|
|||
%call = call i32 @memcmp(i8* %xptr, i8* %yptr, i32 2)
|
||||
%cmp = icmp eq i32 %call, 0
|
||||
ret i1 %cmp
|
||||
; CHECK: %cmp = icmp eq i16 %x, %y
|
||||
; CHECK: ret i1 %cmp
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
; PR1570
|
||||
|
||||
define i1 @f(float %X, float %Y) {
|
||||
entry:
|
||||
%tmp3 = fcmp olt float %X, %Y ; <i1> [#uses=1]
|
||||
%toBoolnot5 = xor i1 %tmp3, true ; <i1> [#uses=1]
|
||||
ret i1 %toBoolnot5
|
||||
; CHECK-LABEL: @f(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: %toBoolnot5 = fcmp uge float %X, %Y
|
||||
; CHECK-NEXT: ret i1 %toBoolnot5
|
||||
}
|
|
@ -1,61 +1,95 @@
|
|||
; This test makes sure that these instructions are properly eliminated.
|
||||
;
|
||||
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
; CHECK-NOT: xor
|
||||
|
||||
define i32 @test1(i32 %A) {
|
||||
%B = xor i32 %A, -1
|
||||
%C = xor i32 %B, -1
|
||||
ret i32 %C
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: ret i32 %A
|
||||
;
|
||||
%B = xor i32 %A, -1
|
||||
%C = xor i32 %B, -1
|
||||
ret i32 %C
|
||||
}
|
||||
|
||||
define i1 @test2(i32 %A, i32 %B) {
|
||||
; Can change into setge
|
||||
%cond = icmp sle i32 %A, %B
|
||||
%Ret = xor i1 %cond, true
|
||||
ret i1 %Ret
|
||||
define i1 @invert_icmp(i32 %A, i32 %B) {
|
||||
; CHECK-LABEL: @invert_icmp(
|
||||
; CHECK-NEXT: [[NOT:%.*]] = icmp sgt i32 %A, %B
|
||||
; CHECK-NEXT: ret i1 [[NOT]]
|
||||
;
|
||||
%cmp = icmp sle i32 %A, %B
|
||||
%not = xor i1 %cmp, true
|
||||
ret i1 %not
|
||||
}
|
||||
|
||||
; PR1570
|
||||
|
||||
define i1 @invert_fcmp(float %X, float %Y) {
|
||||
; CHECK-LABEL: @invert_fcmp(
|
||||
; CHECK-NEXT: [[NOT:%.*]] = fcmp uge float %X, %Y
|
||||
; CHECK-NEXT: ret i1 [[NOT]]
|
||||
;
|
||||
%cmp = fcmp olt float %X, %Y
|
||||
%not = xor i1 %cmp, true
|
||||
ret i1 %not
|
||||
}
|
||||
|
||||
; Test that De Morgan's law can be instcombined.
|
||||
define i32 @test3(i32 %A, i32 %B) {
|
||||
%a = xor i32 %A, -1
|
||||
%b = xor i32 %B, -1
|
||||
%c = and i32 %a, %b
|
||||
%d = xor i32 %c, -1
|
||||
ret i32 %d
|
||||
; CHECK-LABEL: @test3(
|
||||
; CHECK-NEXT: [[C_DEMORGAN:%.*]] = or i32 %A, %B
|
||||
; CHECK-NEXT: ret i32 [[C_DEMORGAN]]
|
||||
;
|
||||
%a = xor i32 %A, -1
|
||||
%b = xor i32 %B, -1
|
||||
%c = and i32 %a, %b
|
||||
%d = xor i32 %c, -1
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
; Test that De Morgan's law can work with constants.
|
||||
define i32 @test4(i32 %A, i32 %B) {
|
||||
%a = xor i32 %A, -1
|
||||
%c = and i32 %a, 5
|
||||
%d = xor i32 %c, -1
|
||||
ret i32 %d
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK-NEXT: [[D1:%.*]] = or i32 %A, -6
|
||||
; CHECK-NEXT: ret i32 [[D1]]
|
||||
;
|
||||
%a = xor i32 %A, -1
|
||||
%c = and i32 %a, 5
|
||||
%d = xor i32 %c, -1
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
; Test the mirror of De Morgan's law.
|
||||
define i32 @test5(i32 %A, i32 %B) {
|
||||
%a = xor i32 %A, -1
|
||||
%b = xor i32 %B, -1
|
||||
%c = or i32 %a, %b
|
||||
%d = xor i32 %c, -1
|
||||
ret i32 %d
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK-NEXT: [[C_DEMORGAN:%.*]] = and i32 %A, %B
|
||||
; CHECK-NEXT: ret i32 [[C_DEMORGAN]]
|
||||
;
|
||||
%a = xor i32 %A, -1
|
||||
%b = xor i32 %B, -1
|
||||
%c = or i32 %a, %b
|
||||
%d = xor i32 %c, -1
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
; PR2298
|
||||
define zeroext i8 @test6(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%tmp1not = xor i32 %a, -1
|
||||
%tmp2not = xor i32 %b, -1
|
||||
%tmp3 = icmp slt i32 %tmp1not, %tmp2not
|
||||
%retval67 = zext i1 %tmp3 to i8
|
||||
ret i8 %retval67
|
||||
; CHECK-LABEL: @test6(
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 %b, %a
|
||||
; CHECK-NEXT: [[RETVAL67:%.*]] = zext i1 [[TMP3]] to i8
|
||||
; CHECK-NEXT: ret i8 [[RETVAL67]]
|
||||
;
|
||||
%tmp1not = xor i32 %a, -1
|
||||
%tmp2not = xor i32 %b, -1
|
||||
%tmp3 = icmp slt i32 %tmp1not, %tmp2not
|
||||
%retval67 = zext i1 %tmp3 to i8
|
||||
ret i8 %retval67
|
||||
}
|
||||
|
||||
define <2 x i1> @test7(<2 x i32> %A, <2 x i32> %B) {
|
||||
%cond = icmp sle <2 x i32> %A, %B
|
||||
%Ret = xor <2 x i1> %cond, <i1 true, i1 true>
|
||||
ret <2 x i1> %Ret
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK-NEXT: [[RET:%.*]] = icmp sgt <2 x i32> %A, %B
|
||||
; CHECK-NEXT: ret <2 x i1> [[RET]]
|
||||
;
|
||||
%cond = icmp sle <2 x i32> %A, %B
|
||||
%Ret = xor <2 x i1> %cond, <i1 true, i1 true>
|
||||
ret <2 x i1> %Ret
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue