From f201b1c91875024224a945862cf394c24c6a29e3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 16 Sep 2019 14:05:19 +0000 Subject: [PATCH] [InstCombine] add/move tests for icmp with add operand; NFC llvm-svn: 371988 --- llvm/test/Transforms/InstCombine/icmp-add.ll | 124 +++++++++++++++++++ llvm/test/Transforms/InstCombine/icmp.ll | 108 ++++------------ 2 files changed, 145 insertions(+), 87 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll index 86d4d7c5735d..87e01d2b3d54 100644 --- a/llvm/test/Transforms/InstCombine/icmp-add.ll +++ b/llvm/test/Transforms/InstCombine/icmp-add.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instcombine -S | FileCheck %s +declare void @use(i32) + ; PR1949 define i1 @test1(i32 %a) { @@ -463,3 +465,125 @@ define i1 @sum_ult_op_uses(i8 %x, i8 %y, i8* %p) { ret i1 %c } +; X + Z >s Y + Z -> X > Y if there is no overflow. +define i1 @common_op_nsw(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: @common_op_nsw( +; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nsw i32 %x, %z + %rhs = add nsw i32 %y, %z + %c = icmp sgt i32 %lhs, %rhs + ret i1 %c +} + +define i1 @common_op_nsw_extra_uses(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: @common_op_nsw_extra_uses( +; CHECK-NEXT: [[LHS:%.*]] = add nsw i32 [[X:%.*]], [[Z:%.*]] +; CHECK-NEXT: call void @use(i32 [[LHS]]) +; CHECK-NEXT: [[RHS:%.*]] = add nsw i32 [[Y:%.*]], [[Z]] +; CHECK-NEXT: call void @use(i32 [[RHS]]) +; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[LHS]], [[RHS]] +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nsw i32 %x, %z + call void @use(i32 %lhs) + %rhs = add nsw i32 %y, %z + call void @use(i32 %rhs) + %c = icmp sgt i32 %lhs, %rhs + ret i1 %c +} + +; X + Z >u Z + Y -> X > Y if there is no overflow. +define i1 @common_op_nuw(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: @common_op_nuw( +; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nuw i32 %x, %z + %rhs = add nuw i32 %z, %y + %c = icmp ugt i32 %lhs, %rhs + ret i1 %c +} + +define i1 @common_op_nuw_extra_uses(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: @common_op_nuw_extra_uses( +; CHECK-NEXT: [[LHS:%.*]] = add nuw i32 [[X:%.*]], [[Z:%.*]] +; CHECK-NEXT: call void @use(i32 [[LHS]]) +; CHECK-NEXT: [[RHS:%.*]] = add nuw i32 [[Z]], [[Y:%.*]] +; CHECK-NEXT: call void @use(i32 [[RHS]]) +; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[LHS]], [[RHS]] +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nuw i32 %x, %z + call void @use(i32 %lhs) + %rhs = add nuw i32 %z, %y + call void @use(i32 %rhs) + %c = icmp ugt i32 %lhs, %rhs + ret i1 %c +} + +define i1 @common_op_nsw_commute(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: @common_op_nsw_commute( +; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nsw i32 %z, %x + %rhs = add nsw i32 %y, %z + %c = icmp slt i32 %lhs, %rhs + ret i1 %c +} + +define i1 @common_op_nuw_commute(i32 %x, i32 %y, i32 %z) { +; CHECK-LABEL: @common_op_nuw_commute( +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nuw i32 %z, %x + %rhs = add nuw i32 %z, %y + %c = icmp ult i32 %lhs, %rhs + ret i1 %c +} + +; X + Y > X -> Y > 0 if there is no overflow. +define i1 @common_op_test29(i32 %x, i32 %y) { +; CHECK-LABEL: @common_op_test29( +; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0 +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nsw i32 %x, %y + %c = icmp sgt i32 %lhs, %x + ret i1 %c +} + +; X + Y > X -> Y > 0 if there is no overflow. +define i1 @sum_nuw(i32 %x, i32 %y) { +; CHECK-LABEL: @sum_nuw( +; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0 +; CHECK-NEXT: ret i1 [[C]] +; + %lhs = add nuw i32 %x, %y + %c = icmp ugt i32 %lhs, %x + ret i1 %c +} + +; X > X + Y -> 0 > Y if there is no overflow. +define i1 @sum_nsw_commute(i32 %x, i32 %y) { +; CHECK-LABEL: @sum_nsw_commute( +; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0 +; CHECK-NEXT: ret i1 [[C]] +; + %rhs = add nsw i32 %x, %y + %c = icmp sgt i32 %x, %rhs + ret i1 %c +} + +; X > X + Y -> 0 > Y if there is no overflow. +define i1 @sum_nuw_commute(i32 %x, i32 %y) { +; CHECK-LABEL: @sum_nuw_commute( +; CHECK-NEXT: ret i1 false +; + %rhs = add nuw i32 %x, %y + %c = icmp ugt i32 %x, %rhs + ret i1 %c +} diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index ec9fc77d9fc8..394138802145 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -521,29 +521,6 @@ define i1 @test24_as1(i64 %i) { ret i1 %cmp } -define i1 @test25(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: @test25( -; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[C]] -; - %lhs = add nsw i32 %x, %z - %rhs = add nsw i32 %y, %z - %c = icmp sgt i32 %lhs, %rhs - ret i1 %c -} - -; X + Z > Y + Z -> X > Y if there is no overflow. -define i1 @test26(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: @test26( -; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[C]] -; - %lhs = add nuw i32 %x, %z - %rhs = add nuw i32 %y, %z - %c = icmp ugt i32 %lhs, %rhs - ret i1 %c -} - ; X - Z > Y - Z -> X > Y if there is no overflow. define i1 @test27(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: @test27( @@ -602,47 +579,32 @@ define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) { ret i1 %c } -; X + Y > X -> Y > 0 if there is no overflow. -define i1 @test29(i32 %x, i32 %y) { -; CHECK-LABEL: @test29( -; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0 -; CHECK-NEXT: ret i1 [[C]] +; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969 + +define i1 @ugt_sub(i32 %xsrc, i32 %y) { +; CHECK-LABEL: @ugt_sub( +; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] ; - %lhs = add nsw i32 %x, %y - %c = icmp sgt i32 %lhs, %x - ret i1 %c + %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization + %sub = sub i32 %x, %y + %cmp = icmp ugt i32 %sub, %x + ret i1 %cmp } -; X + Y > X -> Y > 0 if there is no overflow. -define i1 @test30(i32 %x, i32 %y) { -; CHECK-LABEL: @test30( -; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0 -; CHECK-NEXT: ret i1 [[C]] -; - %lhs = add nuw i32 %x, %y - %c = icmp ugt i32 %lhs, %x - ret i1 %c -} +; Swap operands and predicate. Try a vector type to verify that works too. -; X > X + Y -> 0 > Y if there is no overflow. -define i1 @test31(i32 %x, i32 %y) { -; CHECK-LABEL: @test31( -; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0 -; CHECK-NEXT: ret i1 [[C]] +define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) { +; CHECK-LABEL: @ult_sub( +; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], +; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]] +; CHECK-NEXT: ret <2 x i1> [[CMP]] ; - %rhs = add nsw i32 %x, %y - %c = icmp sgt i32 %x, %rhs - ret i1 %c -} - -; X > X + Y -> 0 > Y if there is no overflow. -define i1 @test32(i32 %x, i32 %y) { -; CHECK-LABEL: @test32( -; CHECK-NEXT: ret i1 false -; - %rhs = add nuw i32 %x, %y - %c = icmp ugt i32 %x, %rhs - ret i1 %c + %x = udiv <2 x i8> %xsrc, ; thwart complexity-based canonicalization + %sub = sub <2 x i8> %x, %y + %cmp = icmp ult <2 x i8> %x, %sub + ret <2 x i1> %cmp } ; X - Y > X -> 0 > Y if there is no overflow. @@ -688,34 +650,6 @@ define i1 @test36(i32 %x, i32 %y) { ret i1 %c } -; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969 - -define i1 @ugt_sub(i32 %xsrc, i32 %y) { -; CHECK-LABEL: @ugt_sub( -; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[CMP]] -; - %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization - %sub = sub i32 %x, %y - %cmp = icmp ugt i32 %sub, %x - ret i1 %cmp -} - -; Swap operands and predicate. Try a vector type to verify that works too. - -define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) { -; CHECK-LABEL: @ult_sub( -; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], -; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]] -; CHECK-NEXT: ret <2 x i1> [[CMP]] -; - %x = udiv <2 x i8> %xsrc, ; thwart complexity-based canonicalization - %sub = sub <2 x i8> %x, %y - %cmp = icmp ult <2 x i8> %x, %sub - ret <2 x i1> %cmp -} - ; X - Y > X - Z -> Z > Y if there is no overflow. define i1 @test37(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: @test37(