xref: /llvm-project/llvm/test/Transforms/DivRemPairs/AMDGPU/div-rem-pairs.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=div-rem-pairs -S -mtriple=amdgcn-amd-amdhsa | FileCheck %s
3
4define i32 @basic(ptr %p, i32 %x, i32 %y) {
5; CHECK-LABEL: define i32 @basic(
6; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
7; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i32 [[X]]
8; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i32 [[Y]]
9; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[X_FROZEN]], [[Y_FROZEN]]
10; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[Y_FROZEN]]
11; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]]
12; CHECK-NEXT:    store i32 [[DIV]], ptr [[P]], align 4
13; CHECK-NEXT:    ret i32 [[REM_DECOMPOSED]]
14;
15  %div = udiv i32 %x, %y
16  %rem = urem i32 %x, %y
17  store i32 %div, ptr %p, align 4
18  ret i32 %rem
19}
20
21define i32 @no_freezes(ptr %p, i32 noundef %x, i32 noundef %y) {
22; CHECK-LABEL: define i32 @no_freezes(
23; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) {
24; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[X]], [[Y]]
25; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[Y]]
26; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[X]], [[TMP1]]
27; CHECK-NEXT:    store i32 [[DIV]], ptr [[P]], align 4
28; CHECK-NEXT:    ret i32 [[REM_DECOMPOSED]]
29;
30  %div = udiv i32 %x, %y
31  %rem = urem i32 %x, %y
32  store i32 %div, ptr %p, align 4
33  ret i32 %rem
34}
35
36define i32 @poison_does_not_freeze(ptr %p, i32 noundef %x, i32 noundef %y) {
37; CHECK-LABEL: define i32 @poison_does_not_freeze(
38; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) {
39; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw i32 [[X]], 5
40; CHECK-NEXT:    [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1
41; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[X2]], [[Y2]]
42; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]]
43; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[X2]], [[TMP1]]
44; CHECK-NEXT:    store i32 [[DIV]], ptr [[P]], align 4
45; CHECK-NEXT:    ret i32 [[REM_DECOMPOSED]]
46;
47  %x2 = shl nuw nsw i32 %x, 5
48  %y2 = add nuw nsw i32 %y, 1
49  %div = udiv i32 %x2, %y2
50  %rem = urem i32 %x2, %y2
51  store i32 %div, ptr %p, align 4
52  ret i32 %rem
53}
54
55define i32 @poison_does_not_freeze_signed(ptr %p, i32 noundef %x, i32 noundef %y) {
56; CHECK-LABEL: define i32 @poison_does_not_freeze_signed(
57; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) {
58; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw i32 [[X]], 5
59; CHECK-NEXT:    [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1
60; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[X2]], [[Y2]]
61; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]]
62; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[X2]], [[TMP1]]
63; CHECK-NEXT:    store i32 [[DIV]], ptr [[P]], align 4
64; CHECK-NEXT:    ret i32 [[REM_DECOMPOSED]]
65;
66  %x2 = shl nuw nsw i32 %x, 5
67  %y2 = add nuw nsw i32 %y, 1
68  %div = sdiv i32 %x2, %y2
69  %rem = srem i32 %x2, %y2
70  store i32 %div, ptr %p, align 4
71  ret i32 %rem
72}
73
74define <4 x i8> @poison_does_not_freeze_vector(ptr %p, <4 x i8> noundef %x, <4 x i8> noundef %y) {
75; CHECK-LABEL: define <4 x i8> @poison_does_not_freeze_vector(
76; CHECK-SAME: ptr [[P:%.*]], <4 x i8> noundef [[X:%.*]], <4 x i8> noundef [[Y:%.*]]) {
77; CHECK-NEXT:    [[X2:%.*]] = shl nuw nsw <4 x i8> [[X]], splat (i8 5)
78; CHECK-NEXT:    [[Y2:%.*]] = add nuw nsw <4 x i8> [[Y]], splat (i8 1)
79; CHECK-NEXT:    [[DIV:%.*]] = udiv <4 x i8> [[X2]], [[Y2]]
80; CHECK-NEXT:    [[TMP1:%.*]] = mul <4 x i8> [[DIV]], [[Y2]]
81; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub <4 x i8> [[X2]], [[TMP1]]
82; CHECK-NEXT:    store <4 x i8> [[DIV]], ptr [[P]], align 4
83; CHECK-NEXT:    ret <4 x i8> [[REM_DECOMPOSED]]
84;
85  %x2 = shl nuw nsw <4 x i8> %x, <i8 5, i8 5, i8 5, i8 5>
86  %y2 = add nuw nsw <4 x i8> %y, <i8 1, i8 1, i8 1, i8 1>
87  %div = udiv <4 x i8> %x2, %y2
88  %rem = urem <4 x i8> %x2, %y2
89  store <4 x i8> %div, ptr %p, align 4
90  ret <4 x i8> %rem
91}
92
93define i32 @explicit_poison_does_not_freeze(ptr %p, i32 noundef %y) {
94; CHECK-LABEL: define i32 @explicit_poison_does_not_freeze(
95; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[Y:%.*]]) {
96; CHECK-NEXT:    [[X:%.*]] = add i32 poison, 1
97; CHECK-NEXT:    [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1
98; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[X]], [[Y2]]
99; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]]
100; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[X]], [[TMP1]]
101; CHECK-NEXT:    store i32 [[DIV]], ptr [[P]], align 4
102; CHECK-NEXT:    ret i32 [[REM_DECOMPOSED]]
103;
104  %x = add i32 poison, 1
105  %y2 = add nuw nsw i32 %y, 1
106  %div = udiv i32 %x, %y2
107  %rem = urem i32 %x, %y2
108  store i32 %div, ptr %p, align 4
109  ret i32 %rem
110}
111
112define i32 @explicit_poison_does_not_freeze_signed(ptr %p, i32 noundef %y) {
113; CHECK-LABEL: define i32 @explicit_poison_does_not_freeze_signed(
114; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[Y:%.*]]) {
115; CHECK-NEXT:    [[X:%.*]] = add i32 poison, 1
116; CHECK-NEXT:    [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1
117; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[X]], [[Y2]]
118; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]]
119; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[X]], [[TMP1]]
120; CHECK-NEXT:    store i32 [[DIV]], ptr [[P]], align 4
121; CHECK-NEXT:    ret i32 [[REM_DECOMPOSED]]
122;
123  %x = add i32 poison, 1
124  %y2 = add nuw nsw i32 %y, 1
125  %div = sdiv i32 %x, %y2
126  %rem = srem i32 %x, %y2
127  store i32 %div, ptr %p, align 4
128  ret i32 %rem
129}
130