@@ -88,3 +88,109 @@ entry:
8888 store i128 %res , ptr %out , align 16
8989 ret void
9090}
91+
92+ ; negative test - wrong constant value
93+ define i128 @i128_ext_split_neg1 (i32 %x ) {
94+ ; CHECK-LABEL: define i128 @i128_ext_split_neg1(
95+ ; CHECK-SAME: i32 [[X:%.*]]) {
96+ ; CHECK-NEXT: [[ENTRY:.*:]]
97+ ; CHECK-NEXT: [[LOWERSRC:%.*]] = sext i32 [[X]] to i64
98+ ; CHECK-NEXT: [[LO:%.*]] = zext i64 [[LOWERSRC]] to i128
99+ ; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X]], 31
100+ ; CHECK-NEXT: [[UPPERSRC:%.*]] = sext i32 [[SIGN]] to i64
101+ ; CHECK-NEXT: [[WIDEN:%.*]] = zext i64 [[UPPERSRC]] to i128
102+ ; CHECK-NEXT: [[HI:%.*]] = shl nuw i128 [[WIDEN]], 65
103+ ; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]
104+ ; CHECK-NEXT: ret i128 [[RES]]
105+ ;
106+ entry:
107+ %LowerSrc = sext i32 %x to i64
108+ %lo = zext i64 %LowerSrc to i128
109+
110+ %sign = ashr i32 %x , 31
111+ %UpperSrc = sext i32 %sign to i64
112+ %widen = zext i64 %UpperSrc to i128
113+ %hi = shl nuw i128 %widen , 65
114+
115+ %res = or disjoint i128 %hi , %lo
116+ ret i128 %res
117+ }
118+
119+ ; negative test - wrong shift value
120+ define i128 @i128_ext_split_neg2 (i32 %x ) {
121+ ; CHECK-LABEL: define i128 @i128_ext_split_neg2(
122+ ; CHECK-SAME: i32 [[X:%.*]]) {
123+ ; CHECK-NEXT: [[ENTRY:.*:]]
124+ ; CHECK-NEXT: [[LOWERSRC:%.*]] = sext i32 [[X]] to i64
125+ ; CHECK-NEXT: [[LO:%.*]] = zext i64 [[LOWERSRC]] to i128
126+ ; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X]], 3
127+ ; CHECK-NEXT: [[UPPERSRC:%.*]] = sext i32 [[SIGN]] to i64
128+ ; CHECK-NEXT: [[WIDEN:%.*]] = zext i64 [[UPPERSRC]] to i128
129+ ; CHECK-NEXT: [[HI:%.*]] = shl nuw i128 [[WIDEN]], 64
130+ ; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]
131+ ; CHECK-NEXT: ret i128 [[RES]]
132+ ;
133+ entry:
134+ %LowerSrc = sext i32 %x to i64
135+ %lo = zext i64 %LowerSrc to i128
136+
137+ %sign = ashr i32 %x , 3
138+ %UpperSrc = sext i32 %sign to i64
139+ %widen = zext i64 %UpperSrc to i128
140+ %hi = shl nuw i128 %widen , 64
141+
142+ %res = or disjoint i128 %hi , %lo
143+ ret i128 %res
144+ }
145+
146+ ; negative test - wrong ext instruction
147+ define i128 @i128_ext_split_neg3 (i32 %x ) {
148+ ; CHECK-LABEL: define i128 @i128_ext_split_neg3(
149+ ; CHECK-SAME: i32 [[X:%.*]]) {
150+ ; CHECK-NEXT: [[ENTRY:.*:]]
151+ ; CHECK-NEXT: [[LO:%.*]] = zext i32 [[X]] to i128
152+ ; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X]], 31
153+ ; CHECK-NEXT: [[UPPERSRC:%.*]] = sext i32 [[SIGN]] to i64
154+ ; CHECK-NEXT: [[WIDEN:%.*]] = zext i64 [[UPPERSRC]] to i128
155+ ; CHECK-NEXT: [[HI:%.*]] = shl nuw i128 [[WIDEN]], 64
156+ ; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]
157+ ; CHECK-NEXT: ret i128 [[RES]]
158+ ;
159+ entry:
160+ %LowerSrc = zext i32 %x to i64
161+ %lo = zext i64 %LowerSrc to i128
162+
163+ %sign = ashr i32 %x , 31
164+ %UpperSrc = sext i32 %sign to i64
165+ %widen = zext i64 %UpperSrc to i128
166+ %hi = shl nuw i128 %widen , 64
167+
168+ %res = or disjoint i128 %hi , %lo
169+ ret i128 %res
170+ }
171+
172+ ; negative test - wrong shift
173+ define i128 @i128_ext_split_neg4 (i32 %x ) {
174+ ; CHECK-LABEL: define i128 @i128_ext_split_neg4(
175+ ; CHECK-SAME: i32 [[X:%.*]]) {
176+ ; CHECK-NEXT: [[ENTRY:.*:]]
177+ ; CHECK-NEXT: [[LOWERSRC:%.*]] = sext i32 [[X]] to i64
178+ ; CHECK-NEXT: [[LO:%.*]] = zext i64 [[LOWERSRC]] to i128
179+ ; CHECK-NEXT: [[SIGN:%.*]] = lshr i32 [[X]], 31
180+ ; CHECK-NEXT: [[WIDEN:%.*]] = zext nneg i32 [[SIGN]] to i128
181+ ; CHECK-NEXT: [[HI:%.*]] = shl nuw nsw i128 [[WIDEN]], 64
182+ ; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]
183+ ; CHECK-NEXT: ret i128 [[RES]]
184+ ;
185+ entry:
186+ %LowerSrc = sext i32 %x to i64
187+ %lo = zext i64 %LowerSrc to i128
188+
189+ %sign = lshr i32 %x , 31
190+ %UpperSrc = sext i32 %sign to i64
191+ %widen = zext i64 %UpperSrc to i128
192+ %hi = shl nuw i128 %widen , 64
193+
194+ %res = or disjoint i128 %hi , %lo
195+ ret i128 %res
196+ }
0 commit comments