xref: /llvm-project/llvm/test/Transforms/InstCombine/umulo-square.ll (revision cdd9221489ec4ed6afc0e5146c2fae4daa8ab260)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes=instcombine -S %s | FileCheck %s
3
4define i1 @umulov_square_i32(i32 %x) {
5; CHECK-LABEL: define i1 @umulov_square_i32(
6; CHECK-SAME: i32 [[X:%.*]]) {
7; CHECK-NEXT:    [[RES:%.*]] = icmp ugt i32 [[X]], 65535
8; CHECK-NEXT:    ret i1 [[RES]]
9;
10  %ret = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %x)
11  %res = extractvalue {i32, i1} %ret, 1
12  ret i1 %res
13}
14
15define i1 @umulov_square_i16(i16 %x) {
16; CHECK-LABEL: define i1 @umulov_square_i16(
17; CHECK-SAME: i16 [[X:%.*]]) {
18; CHECK-NEXT:    [[RES:%.*]] = icmp ugt i16 [[X]], 255
19; CHECK-NEXT:    ret i1 [[RES]]
20;
21  %ret = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %x, i16 %x)
22  %res = extractvalue {i16, i1} %ret, 1
23  ret i1 %res
24}
25
26; Negative tests
27
28define i1 @umulov_square_i13(i13 %x) {
29; CHECK-LABEL: define i1 @umulov_square_i13(
30; CHECK-SAME: i13 [[X:%.*]]) {
31; CHECK-NEXT:    [[RET:%.*]] = call { i13, i1 } @llvm.umul.with.overflow.i13(i13 [[X]], i13 [[X]])
32; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i13, i1 } [[RET]], 1
33; CHECK-NEXT:    ret i1 [[RES]]
34;
35  %ret = call {i13, i1} @llvm.umul.with.overflow.i13(i13 %x, i13 %x)
36  %res = extractvalue {i13, i1} %ret, 1
37  ret i1 %res
38}
39
40define i1 @umulov_square_i32_multiuse(i32 %x) {
41; CHECK-LABEL: define i1 @umulov_square_i32_multiuse(
42; CHECK-SAME: i32 [[X:%.*]]) {
43; CHECK-NEXT:    [[RET:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[X]], i32 [[X]])
44; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[RET]], 1
45; CHECK-NEXT:    [[VAL:%.*]] = extractvalue { i32, i1 } [[RET]], 0
46; CHECK-NEXT:    call void @use(i32 [[VAL]])
47; CHECK-NEXT:    ret i1 [[RES]]
48;
49  %ret = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %x)
50  %res = extractvalue {i32, i1} %ret, 1
51  %val = extractvalue {i32, i1} %ret, 0
52  call void @use(i32 %val)
53  ret i1 %res
54}
55
56define i1 @smulov_square_i32(i32 %x) {
57; CHECK-LABEL: define i1 @smulov_square_i32(
58; CHECK-SAME: i32 [[X:%.*]]) {
59; CHECK-NEXT:    [[RET:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[X]], i32 [[X]])
60; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i32, i1 } [[RET]], 1
61; CHECK-NEXT:    ret i1 [[RES]]
62;
63  %ret = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %x)
64  %res = extractvalue {i32, i1} %ret, 1
65  ret i1 %res
66}
67
68declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32)
69declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
70declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16)
71declare {i13, i1} @llvm.umul.with.overflow.i13(i13, i13)
72declare void @use(i32)
73