diff --git a/llvm/test/Transforms/InstCombine/icmp-of-trunc-ext.ll b/llvm/test/Transforms/InstCombine/icmp-of-trunc-ext.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/icmp-of-trunc-ext.ll @@ -0,0 +1,120 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -passes=instcombine < %s | FileCheck %s + +declare void @llvm.assume(i1) +declare void @use(i16) +define i1 @icmp_trunc_x_trunc_y(i32 %x, i32 %y) { +; CHECK-LABEL: @icmp_trunc_x_trunc_y( +; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 +; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65536 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) +; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) +; CHECK-NEXT: [[X16:%.*]] = trunc i32 [[X]] to i16 +; CHECK-NEXT: [[Y16:%.*]] = trunc i32 [[Y]] to i16 +; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[X16]], [[Y16]] +; CHECK-NEXT: ret i1 [[R]] +; + %x_lb_only = icmp ult i32 %x, 65536 + %y_lb_only = icmp ult i32 %y, 65536 + call void @llvm.assume(i1 %x_lb_only) + call void @llvm.assume(i1 %y_lb_only) + %x16 = trunc i32 %x to i16 + %y16 = trunc i32 %y to i16 + %r = icmp eq i16 %x16, %y16 + ret i1 %r +} + +define i1 @icmp_trunc_x_trunc_y_2(i32 %x, i64 %y) { +; CHECK-LABEL: @icmp_trunc_x_trunc_y_2( +; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 12345 +; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i64 [[Y:%.*]], 65536 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) +; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) +; CHECK-NEXT: [[X16:%.*]] = trunc i32 [[X]] to i16 +; CHECK-NEXT: [[Y16:%.*]] = trunc i64 [[Y]] to i16 +; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[Y16]], [[X16]] +; CHECK-NEXT: ret i1 [[R]] +; + %x_lb_only = icmp ult i32 %x, 12345 + %y_lb_only = icmp ult i64 %y, 65536 + call void @llvm.assume(i1 %x_lb_only) + call void @llvm.assume(i1 %y_lb_only) + %x16 = trunc i32 %x to i16 + %y16 = trunc i64 %y to i16 + %r = icmp eq i16 %y16, %x16 + ret i1 %r +} + +define i1 @icmp_trunc_x_trunc_y_fail_maybe_dirty_upper(i32 %x, i32 %y) { +; CHECK-LABEL: @icmp_trunc_x_trunc_y_fail_maybe_dirty_upper( +; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 +; CHECK-NEXT: [[Y_LB_ONLY:%.*]] = icmp ult i32 [[Y:%.*]], 65537 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) +; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LB_ONLY]]) +; CHECK-NEXT: [[X16:%.*]] = trunc i32 [[X]] to i16 +; CHECK-NEXT: [[Y16:%.*]] = trunc i32 [[Y]] to i16 +; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[X16]], [[Y16]] +; CHECK-NEXT: ret i1 [[R]] +; + %x_lb_only = icmp ult i32 %x, 65536 + %y_lb_only = icmp ult i32 %y, 65537 + call void @llvm.assume(i1 %x_lb_only) + call void @llvm.assume(i1 %y_lb_only) + %x16 = trunc i32 %x to i16 + %y16 = trunc i32 %y to i16 + %r = icmp eq i16 %x16, %y16 + ret i1 %r +} + +define i1 @icmp_trunc_x_zext_y(i32 %x, i8 %y) { +; CHECK-LABEL: @icmp_trunc_x_zext_y( +; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) +; CHECK-NEXT: [[X16:%.*]] = trunc i32 [[X]] to i16 +; CHECK-NEXT: [[Y16:%.*]] = zext i8 [[Y:%.*]] to i16 +; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[X16]], [[Y16]] +; CHECK-NEXT: ret i1 [[R]] +; + %x_lb_only = icmp ult i32 %x, 65536 + call void @llvm.assume(i1 %x_lb_only) + %x16 = trunc i32 %x to i16 + %y16 = zext i8 %y to i16 + %r = icmp eq i16 %x16, %y16 + ret i1 %r +} + +define i1 @icmp_trunc_x_zext_y_2(i64 %x, i8 %y) { +; CHECK-LABEL: @icmp_trunc_x_zext_y_2( +; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i64 [[X:%.*]], 65536 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) +; CHECK-NEXT: [[X16:%.*]] = trunc i64 [[X]] to i16 +; CHECK-NEXT: [[Y16:%.*]] = zext i8 [[Y:%.*]] to i16 +; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[Y16]], [[X16]] +; CHECK-NEXT: ret i1 [[R]] +; + %x_lb_only = icmp ult i64 %x, 65536 + call void @llvm.assume(i1 %x_lb_only) + %x16 = trunc i64 %x to i16 + %y16 = zext i8 %y to i16 + %r = icmp eq i16 %y16, %x16 + ret i1 %r +} + +define i1 @icmp_trunc_x_zext_y_fail_multiuse(i32 %x, i8 %y) { +; CHECK-LABEL: @icmp_trunc_x_zext_y_fail_multiuse( +; CHECK-NEXT: [[X_LB_ONLY:%.*]] = icmp ult i32 [[X:%.*]], 65536 +; CHECK-NEXT: call void @llvm.assume(i1 [[X_LB_ONLY]]) +; CHECK-NEXT: [[X16:%.*]] = trunc i32 [[X]] to i16 +; CHECK-NEXT: [[Y16:%.*]] = zext i8 [[Y:%.*]] to i16 +; CHECK-NEXT: call void @use(i16 [[Y16]]) +; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[X16]], [[Y16]] +; CHECK-NEXT: ret i1 [[R]] +; + %x_lb_only = icmp ult i32 %x, 65536 + call void @llvm.assume(i1 %x_lb_only) + %x16 = trunc i32 %x to i16 + %y16 = zext i8 %y to i16 + call void @use(i16 %y16) + %r = icmp eq i16 %x16, %y16 + ret i1 %r +}