File: narrow.ll

package info (click to toggle)
llvm-toolchain-4.0 1%3A4.0.1-10~deb9u2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 493,332 kB
  • sloc: cpp: 2,698,100; ansic: 552,773; asm: 128,821; python: 121,589; objc: 105,054; sh: 21,174; lisp: 6,758; ml: 5,532; perl: 5,311; pascal: 5,245; makefile: 2,083; cs: 1,868; xml: 686; php: 212; csh: 117
file content (99 lines) | stat: -rw-r--r-- 2,905 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
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s

target datalayout = "n8:16:32:64"

; Eliminating the casts in this testcase (by narrowing the AND operation)
; allows instcombine to realize the function always returns false.

define i1 @test1(i32 %A, i32 %B) {
; CHECK-LABEL: @test1(
; CHECK-NEXT:    ret i1 false
;
  %C1 = icmp slt i32 %A, %B
  %ELIM1 = zext i1 %C1 to i32
  %C2 = icmp sgt i32 %A, %B
  %ELIM2 = zext i1 %C2 to i32
  %C3 = and i32 %ELIM1, %ELIM2
  %ELIM3 = trunc i32 %C3 to i1
  ret i1 %ELIM3
}

; The next 6 (3 logic ops * (scalar+vector)) tests show potential cases for narrowing a bitwise logic op.

define i32 @shrink_xor(i64 %a) {
; CHECK-LABEL: @shrink_xor(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 %a to i32
; CHECK-NEXT:    [[TRUNC:%.*]] = xor i32 [[TMP1]], 1
; CHECK-NEXT:    ret i32 [[TRUNC]]
;
  %xor = xor i64 %a, 1
  %trunc = trunc i64 %xor to i32
  ret i32 %trunc
}

; Vectors (with splat constants) should get the same transform.

define <2 x i32> @shrink_xor_vec(<2 x i64> %a) {
; CHECK-LABEL: @shrink_xor_vec(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> %a to <2 x i32>
; CHECK-NEXT:    [[TRUNC:%.*]] = xor <2 x i32> [[TMP1]], <i32 2, i32 2>
; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]
;
  %xor = xor <2 x i64> %a, <i64 2, i64 2>
  %trunc = trunc <2 x i64> %xor to <2 x i32>
  ret <2 x i32> %trunc
}

; Source and dest types are not in the datalayout.

define i3 @shrink_or(i6 %a) {
; CHECK-LABEL: @shrink_or(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc i6 %a to i3
; CHECK-NEXT:    [[TRUNC:%.*]] = or i3 [[TMP1]], 1
; CHECK-NEXT:    ret i3 [[TRUNC]]
;
  %or = or i6 %a, 33
  %trunc = trunc i6 %or to i3
  ret i3 %trunc
}

; Vectors (with non-splat constants) should get the same transform.

define <2 x i8> @shrink_or_vec(<2 x i16> %a) {
; CHECK-LABEL: @shrink_or_vec(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i16> %a to <2 x i8>
; CHECK-NEXT:    [[TRUNC:%.*]] = or <2 x i8> [[TMP1]], <i8 -1, i8 0>
; CHECK-NEXT:    ret <2 x i8> [[TRUNC]]
;
  %or = or <2 x i16> %a, <i16 -1, i16 256>
  %trunc = trunc <2 x i16> %or to <2 x i8>
  ret <2 x i8> %trunc
}

; We discriminate against weird types.

define i31 @shrink_and(i64 %a) {
; CHECK-LABEL: @shrink_and(
; CHECK-NEXT:    [[AND:%.*]] = and i64 %a, 42
; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[AND]] to i31
; CHECK-NEXT:    ret i31 [[TRUNC]]
;
  %and = and i64 %a, 42
  %trunc = trunc i64 %and to i31
  ret i31 %trunc
}

; Chop the top of the constant(s) if needed.

define <2 x i32> @shrink_and_vec(<2 x i33> %a) {
; CHECK-LABEL: @shrink_and_vec(
; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i33> %a to <2 x i32>
; CHECK-NEXT:    [[TRUNC:%.*]] = and <2 x i32> [[TMP1]], <i32 0, i32 6>
; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]
;
  %and = and <2 x i33> %a, <i33 4294967296, i33 6>
  %trunc = trunc <2 x i33> %and to <2 x i32>
  ret <2 x i32> %trunc
}