From c5f963c2e50939d8cb0d9662ee1ce19fdaf3c158 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 9 Apr 2017 15:44:59 +0000 Subject: [PATCH] [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 --- llvm/test/Transforms/InstCombine/fcmp.ll | 215 ++++++++++++------- llvm/test/Transforms/InstCombine/memcmp-1.ll | 43 ++-- llvm/test/Transforms/InstCombine/not-fcmp.ll | 13 -- llvm/test/Transforms/InstCombine/not.ll | 104 ++++++--- 4 files changed, 238 insertions(+), 137 deletions(-) delete mode 100644 llvm/test/Transforms/InstCombine/not-fcmp.ll diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll index 7fd46f228183..47b5ad07572d 100644 --- a/llvm/test/Transforms/InstCombine/fcmp.ll +++ b/llvm/test/Transforms/InstCombine/fcmp.ll @@ -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 +} + diff --git a/llvm/test/Transforms/InstCombine/memcmp-1.ll b/llvm/test/Transforms/InstCombine/memcmp-1.ll index f9ff479e3add..96516f44e081 100644 --- a/llvm/test/Transforms/InstCombine/memcmp-1.ll +++ b/llvm/test/Transforms/InstCombine/memcmp-1.ll @@ -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 } diff --git a/llvm/test/Transforms/InstCombine/not-fcmp.ll b/llvm/test/Transforms/InstCombine/not-fcmp.ll deleted file mode 100644 index 9718e0b905fc..000000000000 --- a/llvm/test/Transforms/InstCombine/not-fcmp.ll +++ /dev/null @@ -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 ; [#uses=1] - %toBoolnot5 = xor i1 %tmp3, true ; [#uses=1] - ret i1 %toBoolnot5 -; CHECK-LABEL: @f( -; CHECK-NEXT: entry: -; CHECK-NEXT: %toBoolnot5 = fcmp uge float %X, %Y -; CHECK-NEXT: ret i1 %toBoolnot5 -} diff --git a/llvm/test/Transforms/InstCombine/not.ll b/llvm/test/Transforms/InstCombine/not.ll index edb402a125ac..d0c242f65558 100644 --- a/llvm/test/Transforms/InstCombine/not.ll +++ b/llvm/test/Transforms/InstCombine/not.ll @@ -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, - 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, + ret <2 x i1> %Ret }