2
2
; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
3
3
target triple = "riscv64-unknown-unknown-elf"
4
4
5
- define i16 @func2 (i64 %x , i64 %y ) {
6
- ; CHECK-LABEL: @func2 (
5
+ define i16 @basicScenario (i64 %x , i64 %y ) {
6
+ ; CHECK-LABEL: @basicScenario (
7
7
; CHECK-NEXT: entry:
8
8
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[Y:%.*]], 0
9
9
; CHECK-NEXT: [[MUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[Y]], i64 [[X:%.*]])
10
10
; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i64, i1 } [[MUL]], 1
11
- ; CHECK-NEXT: [[SPEC_SELECT :%.*]] = select i1 [[CMP_NOT]], i1 false, i1 [[MUL_OV]]
12
- ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[SPEC_SELECT ]] to i16
11
+ ; CHECK-NEXT: [[TMP0 :%.*]] = select i1 [[CMP_NOT]], i1 false, i1 [[MUL_OV]]
12
+ ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP0 ]] to i16
13
13
; CHECK-NEXT: ret i16 [[CONV]]
14
14
;
15
15
entry:
@@ -27,15 +27,54 @@ land.end: ; preds = %land.rhs, %entry
27
27
ret i16 %conv
28
28
}
29
29
30
- define i16 @noHoist (i64 %x , i64 %y ) {
31
- ; CHECK-LABEL: @noHoist (
30
+ define i16 @samePatternTwice (i64 %x , i64 %y ) {
31
+ ; CHECK-LABEL: @samePatternTwice (
32
32
; CHECK-NEXT: entry:
33
33
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[Y:%.*]], 0
34
- ; CHECK-NEXT: [[ADD2:%.*]] = add nsw i64 [[Y]], [[X:%.*]]
35
- ; CHECK-NEXT: [[MUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[ADD2]], i64 [[X]])
34
+ ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[LAND_END:%.*]], label [[LAND_RHS:%.*]]
35
+ ; CHECK: land.rhs:
36
+ ; CHECK-NEXT: [[MUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[Y]], i64 [[X:%.*]])
37
+ ; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i64, i1 } [[MUL]], 1
38
+ ; CHECK-NEXT: [[MUL2:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[Y]], i64 [[X]])
39
+ ; CHECK-NEXT: [[MUL_OV2:%.*]] = extractvalue { i64, i1 } [[MUL]], 1
40
+ ; CHECK-NEXT: br label [[LAND_END]]
41
+ ; CHECK: land.end:
42
+ ; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[MUL_OV]], [[LAND_RHS]] ]
43
+ ; CHECK-NEXT: [[TMP1:%.*]] = phi i1 [ false, [[ENTRY]] ], [ [[MUL_OV2]], [[LAND_RHS]] ]
44
+ ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP0]] to i16
45
+ ; CHECK-NEXT: [[CONV2:%.*]] = zext i1 [[TMP1]] to i16
46
+ ; CHECK-NEXT: [[TORET:%.*]] = add nsw i16 [[CONV]], [[CONV2]]
47
+ ; CHECK-NEXT: ret i16 [[CONV]]
48
+ ;
49
+ entry:
50
+ %cmp.not = icmp eq i64 %y , 0
51
+ br i1 %cmp.not , label %land.end , label %land.rhs
52
+
53
+ land.rhs: ; preds = %entry
54
+ %mul = tail call { i64 , i1 } @llvm.umul.with.overflow.i64 (i64 %y , i64 %x )
55
+ %mul.ov = extractvalue { i64 , i1 } %mul , 1
56
+ %mul2 = tail call { i64 , i1 } @llvm.umul.with.overflow.i64 (i64 %y , i64 %x )
57
+ %mul.ov2 = extractvalue { i64 , i1 } %mul , 1
58
+ br label %land.end
59
+
60
+ land.end: ; preds = %land.rhs, %entry
61
+ %0 = phi i1 [ false , %entry ], [ %mul.ov , %land.rhs ]
62
+ %1 = phi i1 [ false , %entry ], [ %mul.ov2 , %land.rhs ]
63
+ %conv = zext i1 %0 to i16
64
+ %conv2 = zext i1 %1 to i16
65
+ %toRet = add nsw i16 %conv , %conv2
66
+ ret i16 %conv
67
+ }
68
+
69
+ define i16 @stillHoistNotTooExpensive (i64 %x , i64 %y ) {
70
+ ; CHECK-LABEL: @stillHoistNotTooExpensive(
71
+ ; CHECK-NEXT: entry:
72
+ ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[Y:%.*]], 0
73
+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[Y]], [[X:%.*]]
74
+ ; CHECK-NEXT: [[MUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[ADD]], i64 [[X]])
36
75
; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i64, i1 } [[MUL]], 1
37
- ; CHECK-NEXT: [[SPEC_SELECT :%.*]] = select i1 [[CMP_NOT]], i1 false, i1 [[MUL_OV]]
38
- ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[SPEC_SELECT ]] to i16
76
+ ; CHECK-NEXT: [[TMP0 :%.*]] = select i1 [[CMP_NOT]], i1 false, i1 [[MUL_OV]]
77
+ ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP0 ]] to i16
39
78
; CHECK-NEXT: ret i16 [[CONV]]
40
79
;
41
80
entry:
@@ -53,3 +92,42 @@ land.end: ; preds = %land.rhs, %entry
53
92
%conv = zext i1 %0 to i16
54
93
ret i16 %conv
55
94
}
95
+
96
+ define i16 @noHoistTooExpensive (i64 %x , i64 %y ) {
97
+ ; CHECK-LABEL: @noHoistTooExpensive(
98
+ ; CHECK-NEXT: entry:
99
+ ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[Y:%.*]], 0
100
+ ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[LAND_END:%.*]], label [[LAND_RHS:%.*]]
101
+ ; CHECK: land.rhs:
102
+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[Y]], [[X:%.*]]
103
+ ; CHECK-NEXT: [[ADD2:%.*]] = add nsw i64 [[Y]], [[ADD]]
104
+ ; CHECK-NEXT: [[ADD3:%.*]] = add nsw i64 [[ADD]], [[ADD2]]
105
+ ; CHECK-NEXT: [[ADD4:%.*]] = add nsw i64 [[ADD2]], [[ADD3]]
106
+ ; CHECK-NEXT: [[ADD5:%.*]] = add nsw i64 [[ADD3]], [[ADD4]]
107
+ ; CHECK-NEXT: [[MUL:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[ADD5]], i64 [[X]])
108
+ ; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i64, i1 } [[MUL]], 1
109
+ ; CHECK-NEXT: br label [[LAND_END]]
110
+ ; CHECK: land.end:
111
+ ; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[MUL_OV]], [[LAND_RHS]] ]
112
+ ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP0]] to i16
113
+ ; CHECK-NEXT: ret i16 [[CONV]]
114
+ ;
115
+ entry:
116
+ %cmp.not = icmp eq i64 %y , 0
117
+ br i1 %cmp.not , label %land.end , label %land.rhs
118
+
119
+ land.rhs: ; preds = %entry
120
+ %add = add nsw i64 %y , %x
121
+ %add2 = add nsw i64 %y , %add
122
+ %add3 = add nsw i64 %add , %add2
123
+ %add4 = add nsw i64 %add2 , %add3
124
+ %add5 = add nsw i64 %add3 , %add4
125
+ %mul = tail call { i64 , i1 } @llvm.umul.with.overflow.i64 (i64 %add5 , i64 %x )
126
+ %mul.ov = extractvalue { i64 , i1 } %mul , 1
127
+ br label %land.end
128
+
129
+ land.end: ; preds = %land.rhs, %entry
130
+ %0 = phi i1 [ false , %entry ], [ %mul.ov , %land.rhs ]
131
+ %conv = zext i1 %0 to i16
132
+ ret i16 %conv
133
+ }
0 commit comments