File: mul.ll

package info (click to toggle)
intel-graphics-compiler2 2.16.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 106,644 kB
  • sloc: cpp: 805,640; lisp: 287,672; ansic: 16,414; python: 3,952; yacc: 2,588; lex: 1,666; pascal: 313; sh: 186; makefile: 35
file content (171 lines) | stat: -rw-r--r-- 6,318 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2024 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================


; Note that we could run the test with an additional cleanup pass like EarlyCSE
; to get a tidier output. The current preference is towards the check lines that
; would correspond to the input instructions more explicitly.
; RUN: igc_opt --opaque-pointers -debugify --igc-gen-specific-pattern -check-debugify -S < %s 2>&1 | FileCheck %s
; ------------------------------------------------
; GenSpecificPattern:
; ------------------------------------------------

; Debug-info related check
; CHECK-NOT: WARNING
; CHECK: CheckModuleDebugify: PASS

define void @test_simple_mul_pow2(i32 %arg) {
  %1 = mul i32 %arg, 16
  call void @use.i32(i32 %1)
  ret void
}
; CHECK-LABEL: @test_simple_mul_pow2(i32 %arg
; CHECK:       %[[SHL:.+]] = shl i32 %arg, 4
; CHECK:       call void @use.i32(i32 %[[SHL]])
; CHECK:       ret void

; COM: Negative edge case test
define void @test_mul_pow2_skip_ones(i32 %arg) {
  %1 = mul i32 %arg, 1
  call void @use.i32(i32 %1)
  %2 = mul i32 -1, %arg
  call void @use.i32(i32 %2)
  ret void
}
; CHECK-LABEL: @test_mul_pow2_skip_ones(i32 %arg
; CHECK:       %[[MUL_PLUS:.+]] = mul i32 %arg, 1
; CHECK:       call void @use.i32(i32 %[[MUL_PLUS]])
; CHECK:       %[[MUL_MINUS:.+]] = mul i32 -1, %arg
; CHECK:       call void @use.i32(i32 %[[MUL_MINUS]])
; CHECK:       ret void

define void @test_mul_pow2_overflow_flags(i64 %arg) {
  %1 = mul nsw i64 %arg, 256
  call void @use.i64(i64 %1)
  %2 = mul nuw i64 %arg, 256
  call void @use.i64(i64 %2)
  %3 = mul nuw nsw i64 %arg, 1024
  call void @use.i64(i64 %3)
  ret void
}
; CHECK-LABEL: @test_mul_pow2_overflow_flags(i64 %arg
; CHECK:       %[[SHL_NSW:.+]] = shl nsw i64 %arg, 8
; CHECK:       call void @use.i64(i64 %[[SHL_NSW]])
; CHECK:       %[[SHL_NUW:.+]] = shl nuw i64 %arg, 8
; CHECK:       call void @use.i64(i64 %[[SHL_NUW]])
; CHECK:       %[[SHL_NUW_NSW:.+]] = shl nuw nsw i64 %arg, 10
; CHECK:       call void @use.i64(i64 %[[SHL_NUW_NSW]])
; CHECK:       ret void

define void @test_mul_neg_pow2_overflow_flags(i64 %arg) {
  %1 = mul nsw i64 %arg, -256
  call void @use.i64(i64 %1)
  %2 = mul nuw i64 %arg, -256
  call void @use.i64(i64 %2)
  %3 = mul nuw nsw i64 %arg, -1024
  call void @use.i64(i64 %3)
  ret void
}
; CHECK-LABEL: @test_mul_neg_pow2_overflow_flags(i64 %arg
; COM: Only 'mul's without NUW can be transformed
; CHECK:       %[[SHL_NSW:.+]] = shl nsw i64 %arg, 8
; CHECK:       %[[NEG_NSW:.+]] = sub nsw i64 0, %[[SHL_NSW]]
; CHECK:       call void @use.i64(i64 %[[NEG_NSW]])
; CHECK:       %[[MUL_NUW:.+]] = mul nuw i64 %arg, -256
; CHECK:       call void @use.i64(i64 %[[MUL_NUW]])
; CHECK:       %[[MUL_NUW_NSW:.+]] = mul nuw nsw i64 %arg, -1024
; CHECK:       call void @use.i64(i64 %[[MUL_NUW_NSW]])
; CHECK:       ret void

define void @test_mul_neg_pow2_with_binops(i32 %arg0, i32 %arg1, i32 %arg2) {
entry:
; COM: The mul itself + simple use
  %0 = mul i32 %arg0, -1024
  call void @use.i32(i32 %0)
  br label %.add1
.add1:
; COM: mul + addend
  %1 = add i32 %0, %arg1
  call void @use.i32(i32 %1)
  br label %.add2
.add2:
; COM: addend + mul
  %2 = add i32 %arg2, %0
  call void @use.i32(i32 %2)
  ret void
}
; CHECK-LABEL: @test_mul_neg_pow2_with_binops(i32 %arg0, i32 %arg1, i32 %arg2
; COM: The mul itself + simple use
; CHECK:     entry:
; CHECK:       %[[SHL:.+]] = shl i32 %arg0, 10
; CHECK:       %[[NEG:.+]] = sub i32 0, %[[SHL]]
; CHECK:       call void @use.i32(i32 %[[NEG]])
; CHECK:     br label %.add1
; COM: mul + addend -> addend - shl
; CHECK:     .add1:
; CHECK:       %[[SUB1:.+]] = sub i32 %arg1, %[[SHL]]
; CHECK:       call void @use.i32(i32 %[[SUB1]])
; CHECK:       br label %.add2
; COM: addend + mul -> addend - shl
; CHECK:     .add2:
; CHECK:       %[[SUB2:.+]] = sub i32 %arg2, %[[SHL]]
; CHECK:       call void @use.i32(i32 %[[SUB2]])
; CHECK:       ret void

define void @test_mul_neg_pow2_with_binops_overflow_flags(i64 %arg0, i64 %arg1) {
; COM: 'mul' with no flags - 'add's with all combinations of flags
  %1 = mul i64 %arg0, -256
  %2 = add i64 %1, %arg1
  call void @use.i64(i64 %2)
  %3 = add nuw i64 %arg1, %1
  call void @use.i64(i64 %3)
  %4 = add nsw i64 %1, %arg1
  call void @use.i64(i64 %4)
  %5 = add nuw nsw i64 %arg1, %1
  call void @use.i64(i64 %5)
; COM: 'mul' with 'nsw' - 'add's with all combinations of flags
  %6 = mul nsw i64 %arg0, -512
  %7 = add i64 %6, %arg1
  call void @use.i64(i64 %7)
  %8 = add nuw i64 %arg1, %6
  call void @use.i64(i64 %8)
  %9 = add nsw i64 %6, %arg1
  call void @use.i64(i64 %9)
  %10 = add nuw nsw i64 %arg1, %6
  call void @use.i64(i64 %10)
  ret void
}
; CHECK-LABEL: @test_mul_neg_pow2_with_binops_overflow_flags(i64 %arg0, i64 %arg1
; COM: 'mul' with no flags
; CHECK:       %[[SHL_NO_FLAG:.+]] = shl i64 %arg0, 8
; CHECK:       %[[NEG_NO_FLAG:.+]] = sub i64 0, %[[SHL_NO_FLAG]]
; COM: 'add's without 'nsw' can be simplified
; CHECK:       %[[ADD_NO_FLAG:.+]] = sub i64 %arg1, %[[SHL_NO_FLAG]]
; CHECK:       call void @use.i64(i64 %[[ADD_NO_FLAG]])
; CHECK:       %[[ADD_NUW:.+]] = sub nuw i64 %arg1, %[[SHL_NO_FLAG]]
; CHECK:       call void @use.i64(i64 %[[ADD_NUW]])
; CHECK:       %[[ADD_NSW:.+]] = add nsw i64 %[[NEG_NO_FLAG]], %arg1
; CHECK:       call void @use.i64(i64 %[[ADD_NSW]])
; CHECK:       %[[ADD_NUW_NSW:.+]] = add nuw nsw i64 %arg1, %[[NEG_NO_FLAG]]
; CHECK:       call void @use.i64(i64 %[[ADD_NUW_NSW]])
; COM: 'mul' with 'nsw'
; CHECK:       %[[SHL_NSW:.+]] = shl nsw i64 %arg0, 9
; CHECK:       %[[NEG_NSW:.+]] = sub nsw i64 0, %[[SHL_NSW]]
; COM: Any 'add's with 'nsw' can be simplified
; CHECK:       %[[ADD_NO_FLAG:.+]] = add i64 %[[NEG_NSW]], %arg1
; CHECK:       call void @use.i64(i64 %[[ADD_NO_FLAG]])
; CHECK:       %[[ADD_NUW:.+]] = add nuw i64 %arg1, %[[NEG_NSW]]
; CHECK:       call void @use.i64(i64 %[[ADD_NUW]])
; CHECK:       %[[ADD_NSW:.+]] = sub nsw i64 %arg1, %[[SHL_NSW]]
; CHECK:       call void @use.i64(i64 %[[ADD_NSW]])
; CHECK:       %[[ADD_NUW_NSW:.+]] = sub nuw nsw i64 %arg1, %[[SHL_NSW]]
; CHECK:       call void @use.i64(i64 %[[ADD_NUW_NSW]])
; CHECK:       ret void

declare void @use.i64(i64)
declare void @use.i32(i32)