llvm.org GIT mirror llvm / 7eb8348
[InstSimplify] tests for D48828: fold extraction from std::pair This commit includes unit tests for D48828, which enhances InstSimplify to enable jump threading with a method whose return type is std::pair<int, bool> or std::pair<bool, int>. I am going to commit the actual transformation later. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338107 91177308-0d34-0410-b5e6-96231b3b80d8 Hiroshi Inoue 1 year, 3 months ago
3 changed file(s) with 305 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
963963 %or = or i32 %a, %nega
964964 ret i32 %or
965965 }
966
967 define i64 @shl_or_and1(i32 %a, i1 %b) {
968 ; CHECK-LABEL: @shl_or_and1(
969 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64
970 ; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[B:%.*]] to i64
971 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP1]], 32
972 ; CHECK-NEXT: [[TMP4:%.*]] = or i64 [[TMP2]], [[TMP3]]
973 ; CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 1
974 ; CHECK-NEXT: ret i64 [[TMP5]]
975 ;
976 %tmp1 = zext i32 %a to i64
977 %tmp2 = zext i1 %b to i64
978 %tmp3 = shl nuw i64 %tmp1, 32
979 %tmp4 = or i64 %tmp2, %tmp3
980 %tmp5 = and i64 %tmp4, 1
981 ret i64 %tmp5
982 }
983
984 define i64 @shl_or_and2(i32 %a, i1 %b) {
985 ; CHECK-LABEL: @shl_or_and2(
986 ; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[B:%.*]] to i64
987 ; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[A:%.*]] to i64
988 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP1]], 32
989 ; CHECK-NEXT: [[TMP4:%.*]] = or i64 [[TMP2]], [[TMP3]]
990 ; CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 4294967296
991 ; CHECK-NEXT: ret i64 [[TMP5]]
992 ;
993 %tmp1 = zext i1 %b to i64
994 %tmp2 = zext i32 %a to i64
995 %tmp3 = shl nuw i64 %tmp1, 32
996 %tmp4 = or i64 %tmp2, %tmp3
997 %tmp5 = and i64 %tmp4, 4294967296
998 ret i64 %tmp5
999 }
1000
1001 define i32 @shl_or_and3(i32 %a, i32 %b) {
1002 ; concatinate two 32-bit integers and extract lower 32-bit
1003 ; CHECK-LABEL: @shl_or_and3(
1004 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64
1005 ; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[B:%.*]] to i64
1006 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP1]], 32
1007 ; CHECK-NEXT: [[TMP4:%.*]] = or i64 [[TMP2]], [[TMP3]]
1008 ; CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 4294967295
1009 ; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32
1010 ; CHECK-NEXT: ret i32 [[TMP6]]
1011 ;
1012 %tmp1 = zext i32 %a to i64
1013 %tmp2 = zext i32 %b to i64
1014 %tmp3 = shl nuw i64 %tmp1, 32
1015 %tmp4 = or i64 %tmp2, %tmp3
1016 %tmp5 = and i64 %tmp4, 4294967295
1017 %tmp6 = trunc i64 %tmp5 to i32
1018 ret i32 %tmp6
1019 }
1020
1021 define i32 @shl_or_and4(i16 %a, i16 %b) {
1022 ; concatinate two 16-bit integers and extract higher 16-bit
1023 ; CHECK-LABEL: @shl_or_and4(
1024 ; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[A:%.*]] to i32
1025 ; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[B:%.*]] to i32
1026 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 [[TMP1]], 16
1027 ; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
1028 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], -65536
1029 ; CHECK-NEXT: ret i32 [[TMP5]]
1030 ;
1031 %tmp1 = zext i16 %a to i32
1032 %tmp2 = zext i16 %b to i32
1033 %tmp3 = shl nuw i32 %tmp1, 16
1034 %tmp4 = or i32 %tmp2, %tmp3
1035 %tmp5 = and i32 %tmp4, 4294901760 ; mask with 0xFFFF0000
1036 ret i32 %tmp5
1037 }
1038
1039 define i64 @shl_or_and5(i64 %a, i1 %b) {
1040 ; CHECK-LABEL: @shl_or_and5(
1041 ; CHECK-NEXT: [[TMP1:%.*]] = zext i64 [[A:%.*]] to i128
1042 ; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[B:%.*]] to i128
1043 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i128 [[TMP1]], 64
1044 ; CHECK-NEXT: [[TMP4:%.*]] = or i128 [[TMP2]], [[TMP3]]
1045 ; CHECK-NEXT: [[TMP5:%.*]] = and i128 [[TMP4]], 1
1046 ; CHECK-NEXT: [[TMP6:%.*]] = trunc i128 [[TMP5]] to i64
1047 ; CHECK-NEXT: ret i64 [[TMP6]]
1048 ;
1049 %tmp1 = zext i64 %a to i128
1050 %tmp2 = zext i1 %b to i128
1051 %tmp3 = shl nuw i128 %tmp1, 64
1052 %tmp4 = or i128 %tmp2, %tmp3
1053 %tmp5 = and i128 %tmp4, 1
1054 %tmp6 = trunc i128 %tmp5 to i64
1055 ret i64 %tmp6
1056 }
1057
1058 define i32 @shl_or_and6(i16 %a, i16 %b) {
1059 ; A variation of above test case, but fails due to the mask value
1060 ; CHECK-LABEL: @shl_or_and6(
1061 ; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[A:%.*]] to i32
1062 ; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[B:%.*]] to i32
1063 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 [[TMP1]], 16
1064 ; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
1065 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], -65535
1066 ; CHECK-NEXT: ret i32 [[TMP5]]
1067 ;
1068 %tmp1 = zext i16 %a to i32
1069 %tmp2 = zext i16 %b to i32
1070 %tmp3 = shl nuw i32 %tmp1, 16
1071 %tmp4 = or i32 %tmp2, %tmp3
1072 %tmp5 = and i32 %tmp4, 4294901761 ; mask with 0xFFFF0001
1073 ret i32 %tmp5
1074 }
1075
1076 define i32 @shl_or_and7(i16 %a, i16 %b) {
1077 ; A variation of above test case, but fails due to the mask value
1078 ; CHECK-LABEL: @shl_or_and7(
1079 ; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[A:%.*]] to i32
1080 ; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[B:%.*]] to i32
1081 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 [[TMP1]], 16
1082 ; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
1083 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], -131072
1084 ; CHECK-NEXT: ret i32 [[TMP5]]
1085 ;
1086 %tmp1 = zext i16 %a to i32
1087 %tmp2 = zext i16 %b to i32
1088 %tmp3 = shl nuw i32 %tmp1, 16
1089 %tmp4 = or i32 %tmp2, %tmp3
1090 %tmp5 = and i32 %tmp4, 4294836224 ; mask with 0xFFFE0000
1091 ret i32 %tmp5
1092 }
1093
1094 define i32 @shl_or_and8(i16 %a, i16 %b) {
1095 ; A variation of above test case, but fails due to the mask value
1096 ; CHECK-LABEL: @shl_or_and8(
1097 ; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[A:%.*]] to i32
1098 ; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[B:%.*]] to i32
1099 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 [[TMP1]], 16
1100 ; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
1101 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 131071
1102 ; CHECK-NEXT: ret i32 [[TMP5]]
1103 ;
1104 %tmp1 = zext i16 %a to i32
1105 %tmp2 = zext i16 %b to i32
1106 %tmp3 = shl nuw i32 %tmp1, 16
1107 %tmp4 = or i32 %tmp2, %tmp3
1108 %tmp5 = and i32 %tmp4, 131071 ; mask with 0x1FFFF
1109 ret i32 %tmp5
1110 }
174174 ret <2 x i8> %r
175175 }
176176
177 define i32 @shl_or_shr(i32 %a, i32 %b) {
178 ; CHECK-LABEL: @shl_or_shr(
179 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64
180 ; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[B:%.*]] to i64
181 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP1]], 32
182 ; CHECK-NEXT: [[TMP4:%.*]] = or i64 [[TMP2]], [[TMP3]]
183 ; CHECK-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP4]], 32
184 ; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32
185 ; CHECK-NEXT: ret i32 [[TMP6]]
186 ;
187 %tmp1 = zext i32 %a to i64
188 %tmp2 = zext i32 %b to i64
189 %tmp3 = shl nuw i64 %tmp1, 32
190 %tmp4 = or i64 %tmp2, %tmp3
191 %tmp5 = lshr i64 %tmp4, 32
192 %tmp6 = trunc i64 %tmp5 to i32
193 ret i32 %tmp6
194 }
195
196 define i32 @shl_or_shr2(i32 %a, i32 %b) {
197 ; Since shift count of shl is smaller than the size of %b, OR cannot be eliminated.
198 ; CHECK-LABEL: @shl_or_shr2(
199 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A:%.*]] to i64
200 ; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[B:%.*]] to i64
201 ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP1]], 31
202 ; CHECK-NEXT: [[TMP4:%.*]] = or i64 [[TMP2]], [[TMP3]]
203 ; CHECK-NEXT: [[TMP5:%.*]] = lshr i64 [[TMP4]], 31
204 ; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i32
205 ; CHECK-NEXT: ret i32 [[TMP6]]
206 ;
207 %tmp1 = zext i32 %a to i64
208 %tmp2 = zext i32 %b to i64
209 %tmp3 = shl nuw i64 %tmp1, 31
210 %tmp4 = or i64 %tmp2, %tmp3
211 %tmp5 = lshr i64 %tmp4, 31
212 %tmp6 = trunc i64 %tmp5 to i32
213 ret i32 %tmp6
214 }
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt < %s -newgvn -S | FileCheck %s
2 ; RUN: opt < %s -newgvn -jump-threading -S | FileCheck --check-prefix=CHECK-JT %s
3 ; This test is expected to fail until the transformation is committed.
4 ; XFAIL: *
5
6 define signext i32 @testBI(i32 signext %v) {
7 ; Test with std::pair
8 ; based on the following C++ code
9 ; std::pair callee(int v) {
10 ; int a = dummy(v);
11 ; if (a) return std::make_pair(true, dummy(a));
12 ; else return std::make_pair(v < 0, v);
13 ; }
14 ; int func(int v) {
15 ; std::pair rc = callee(v);
16 ; if (rc.first) dummy(0);
17 ; return rc.second;
18 ; }
19 ; CHECK-LABEL: @testBI(
20 ; CHECK: _ZL6calleei.exit:
21 ; CHECK: [[PHIOFOPS:%.*]] = phi i64 [ 1, %if.then.i ], [ {{%.*}}, %if.else.i ]
22 ; CHECK: [[TOBOOL:%.*]] = icmp eq i64 [[PHIOFOPS]], 0
23 ;
24 ; CHECK-JT-LABEL: @testBI(
25 ; CHECK-JT: _ZL6calleei.exit.thread:
26 ;
27
28 entry:
29 %call.i = call signext i32 @dummy(i32 signext %v)
30 %tobool.i = icmp eq i32 %call.i, 0
31 br i1 %tobool.i, label %if.else.i, label %if.then.i
32
33 if.then.i: ; preds = %entry
34 %call2.i = call signext i32 @dummy(i32 signext %call.i)
35 %retval.sroa.22.0.insert.ext.i.i = zext i32 %call2.i to i64
36 %retval.sroa.22.0.insert.shift.i.i = shl nuw i64 %retval.sroa.22.0.insert.ext.i.i, 32
37 %retval.sroa.0.0.insert.insert.i.i = or i64 %retval.sroa.22.0.insert.shift.i.i, 1
38 br label %_ZL6calleei.exit
39
40 if.else.i: ; preds = %entry
41 %.lobit.i = lshr i32 %v, 31
42 %0 = zext i32 %.lobit.i to i64
43 %retval.sroa.22.0.insert.ext.i8.i = zext i32 %v to i64
44 %retval.sroa.22.0.insert.shift.i9.i = shl nuw i64 %retval.sroa.22.0.insert.ext.i8.i, 32
45 %retval.sroa.0.0.insert.insert.i11.i = or i64 %retval.sroa.22.0.insert.shift.i9.i, %0
46 br label %_ZL6calleei.exit
47
48 _ZL6calleei.exit: ; preds = %if.then.i, %if.else.i
49 %retval.sroa.0.0.i = phi i64 [ %retval.sroa.0.0.insert.insert.i.i, %if.then.i ], [ %retval.sroa.0.0.insert.insert.i11.i, %if.else.i ]
50 %rc.sroa.43.0.extract.shift = lshr i64 %retval.sroa.0.0.i, 32
51 %rc.sroa.43.0.extract.trunc = trunc i64 %rc.sroa.43.0.extract.shift to i32
52 %1 = and i64 %retval.sroa.0.0.i, 1
53 %tobool = icmp eq i64 %1, 0
54 br i1 %tobool, label %if.end, label %if.then
55
56 if.then: ; preds = %_ZL6calleei.exit
57 %call1 = call signext i32 @dummy(i32 signext 0)
58 br label %if.end
59
60 if.end: ; preds = %_ZL6calleei.exit, %if.then
61 ret i32 %rc.sroa.43.0.extract.trunc
62 }
63
64
65 define signext i32 @testIB(i32 signext %v) {
66 ; Test with std::pair
67 ; based on the following C++ code
68 ; std::pair callee(int v) {
69 ; int a = dummy(v);
70 ; if (a) return std::make_pair(dummy(v), true);
71 ; else return std::make_pair(v, v < 0);
72 ; }
73 ; int func(int v) {
74 ; std::pair rc = callee(v);
75 ; if (rc.second) dummy(0);
76 ; return rc.first;
77 ; }
78 ; CHECK-LABEL: @testIB(
79 ; CHECK: _ZL6calleei.exit:
80 ; CHECK: [[PHIOFOPS:%.*]] = phi i64 [ 4294967296, %if.then.i ], [ {{%.*}}, %if.else.i ]
81 ; CHECK: [[TOBOOL:%.*]] = icmp eq i64 [[PHIOFOPS]], 0
82 ;
83 ; CHECK-JT-LABEL: @testIB(
84 ; CHECK-JT: _ZL6calleei.exit.thread:
85 ;
86
87 entry:
88 %call.i = call signext i32 @dummy(i32 signext %v)
89 %tobool.i = icmp eq i32 %call.i, 0
90 br i1 %tobool.i, label %if.else.i, label %if.then.i
91
92 if.then.i: ; preds = %entry
93 %call1.i = call signext i32 @dummy(i32 signext %v)
94 %retval.sroa.0.0.insert.ext.i.i = zext i32 %call1.i to i64
95 %retval.sroa.0.0.insert.insert.i.i = or i64 %retval.sroa.0.0.insert.ext.i.i, 4294967296
96 br label %_ZL6calleei.exit
97
98 if.else.i: ; preds = %entry
99 %.lobit.i = lshr i32 %v, 31
100 %0 = zext i32 %.lobit.i to i64
101 %retval.sroa.2.0.insert.shift.i8.i = shl nuw nsw i64 %0, 32
102 %retval.sroa.0.0.insert.ext.i9.i = zext i32 %v to i64
103 %retval.sroa.0.0.insert.insert.i10.i = or i64 %retval.sroa.2.0.insert.shift.i8.i, %retval.sroa.0.0.insert.ext.i9.i
104 br label %_ZL6calleei.exit
105
106 _ZL6calleei.exit: ; preds = %if.then.i, %if.else.i
107 %retval.sroa.0.0.i = phi i64 [ %retval.sroa.0.0.insert.insert.i.i, %if.then.i ], [ %retval.sroa.0.0.insert.insert.i10.i, %if.else.i ]
108 %rc.sroa.0.0.extract.trunc = trunc i64 %retval.sroa.0.0.i to i32
109 %1 = and i64 %retval.sroa.0.0.i, 4294967296
110 %tobool = icmp eq i64 %1, 0
111 br i1 %tobool, label %if.end, label %if.then
112
113 if.then: ; preds = %_ZL6calleei.exit
114 %call1 = call signext i32 @dummy(i32 signext 0)
115 br label %if.end
116
117 if.end: ; preds = %_ZL6calleei.exit, %if.then
118 ret i32 %rc.sroa.0.0.extract.trunc
119 }
120
121 declare signext i32 @dummy(i32 signext %v)