diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -2,6 +2,8 @@ ; RUN: opt < %s -instsimplify -S | FileCheck %s target datalayout = "p:32:32-p1:64:64" +declare void @llvm.assume(i1) + define i1 @ptrtoint() { ; CHECK-LABEL: @ptrtoint( ; CHECK-NEXT: ret i1 false @@ -576,6 +578,94 @@ ret i1 %C } +define i1 @lshr_nonzero1(i32 %x) { +; CHECK-LABEL: @lshr_nonzero1( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = lshr i32 %x, 1 + %cmp = icmp eq i32 %lhs, %x + ret i1 %cmp +} + +define i1 @lshr_nonzero2(i32 %x) { +; CHECK-LABEL: @lshr_nonzero2( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = lshr i32 %x, 1 + %cmp = icmp uge i32 %lhs, %x + ret i1 %cmp +} + +define i1 @lshr_nonzero3(i32 %x) { +; CHECK-LABEL: @lshr_nonzero3( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = lshr i32 %x, 1 + %cmp = icmp ne i32 %lhs, %x + ret i1 %cmp +} + +define i1 @lshr_nonzero4(i32 %x) { +; CHECK-LABEL: @lshr_nonzero4( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = lshr i32 %x, 1 + %cmp = icmp ult i32 %lhs, %x + ret i1 %cmp +} + +; Negative test - unknown shift amount +define i1 @lshr_nonzero_neg1(i32 %x, i32 %c) { +; CHECK-LABEL: @lshr_nonzero_neg1( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X]], [[C:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = lshr i32 %x, %c + %cmp = icmp ult i32 %lhs, %x + ret i1 %cmp +} + +; Negative test - x may be zero +define i1 @lshr_nonzero_neg2(i32 %x, i32 %c) { +; CHECK-LABEL: @lshr_nonzero_neg2( +; CHECK-NEXT: [[LHS:%.*]] = lshr i32 [[X:%.*]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %lhs = lshr i32 %x, 1 + %cmp = icmp ult i32 %lhs, %x + ret i1 %cmp +} + define i1 @ashr1(i32 %x) { ; CHECK-LABEL: @ashr1( ; CHECK-NEXT: ret i1 false @@ -888,6 +978,94 @@ ret i1 %C } +define i1 @udiv_nonzero1(i32 %x) { +; CHECK-LABEL: @udiv_nonzero1( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], 3 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = udiv i32 %x, 3 + %cmp = icmp eq i32 %lhs, %x + ret i1 %cmp +} + +define i1 @udiv_nonzero2(i32 %x) { +; CHECK-LABEL: @udiv_nonzero2( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], 3 +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = udiv i32 %x, 3 + %cmp = icmp uge i32 %lhs, %x + ret i1 %cmp +} + +define i1 @udiv_nonzero3(i32 %x) { +; CHECK-LABEL: @udiv_nonzero3( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], 3 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = udiv i32 %x, 3 + %cmp = icmp ne i32 %lhs, %x + ret i1 %cmp +} + +define i1 @udiv_nonzero4(i32 %x) { +; CHECK-LABEL: @udiv_nonzero4( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], 3 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = udiv i32 %x, 3 + %cmp = icmp ult i32 %lhs, %x + ret i1 %cmp +} + +; Negative test - unknown divisor +define i1 @udiv_nonzero_neg1(i32 %x, i32 %c) { +; CHECK-LABEL: @udiv_nonzero_neg1( +; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_NE_0]]) +; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X]], [[C:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %x_ne_0 = icmp ne i32 %x, 0 + call void @llvm.assume(i1 %x_ne_0) + %lhs = udiv i32 %x, %c + %cmp = icmp ult i32 %lhs, %x + ret i1 %cmp +} + +; Negative test - x may be zero +define i1 @udiv_nonzero_neg2(i32 %x, i32 %c) { +; CHECK-LABEL: @udiv_nonzero_neg2( +; CHECK-NEXT: [[LHS:%.*]] = udiv i32 [[X:%.*]], 3 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LHS]], [[X]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %lhs = udiv i32 %x, 3 + %cmp = icmp ult i32 %lhs, %x + ret i1 %cmp +} + ; Square of a non-zero number is non-zero if there is no overflow. define i1 @mul1(i32 %X) { ; CHECK-LABEL: @mul1(