@@ -222,7 +222,6 @@ entry:
222222 ret i32 %add
223223}
224224
225- ; NOTE: This will become qc.shladd once support is added
226225define dso_local i32 @pow2 (i32 %a , i32 %b ) local_unnamed_addr #0 {
227226; RV32IM-LABEL: pow2:
228227; RV32IM: # %bb.0: # %entry
@@ -232,14 +231,12 @@ define dso_local i32 @pow2(i32 %a, i32 %b) local_unnamed_addr #0 {
232231;
233232; RV32IMXQCIAC-LABEL: pow2:
234233; RV32IMXQCIAC: # %bb.0: # %entry
235- ; RV32IMXQCIAC-NEXT: slli a1, a1, 5
236- ; RV32IMXQCIAC-NEXT: add a0, a0, a1
234+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a1, 5
237235; RV32IMXQCIAC-NEXT: ret
238236;
239237; RV32IZBAMXQCIAC-LABEL: pow2:
240238; RV32IZBAMXQCIAC: # %bb.0: # %entry
241- ; RV32IZBAMXQCIAC-NEXT: slli a1, a1, 5
242- ; RV32IZBAMXQCIAC-NEXT: add a0, a0, a1
239+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a1, 5
243240; RV32IZBAMXQCIAC-NEXT: ret
244241entry:
245242 %mul = mul nsw i32 %b , 32
@@ -269,3 +266,200 @@ entry:
269266 %add = add nsw i32 %mul , %a
270267 ret i32 %add
271268}
269+
270+ define dso_local i32 @shladd (i32 %a , i32 %b ) local_unnamed_addr #0 {
271+ ; RV32IM-LABEL: shladd:
272+ ; RV32IM: # %bb.0: # %entry
273+ ; RV32IM-NEXT: slli a1, a1, 31
274+ ; RV32IM-NEXT: add a0, a1, a0
275+ ; RV32IM-NEXT: ret
276+ ;
277+ ; RV32IMXQCIAC-LABEL: shladd:
278+ ; RV32IMXQCIAC: # %bb.0: # %entry
279+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a1, 31
280+ ; RV32IMXQCIAC-NEXT: ret
281+ ;
282+ ; RV32IZBAMXQCIAC-LABEL: shladd:
283+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
284+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a1, 31
285+ ; RV32IZBAMXQCIAC-NEXT: ret
286+ entry:
287+ %shl = shl nsw i32 %b , 31
288+ %add = add nsw i32 %shl , %a
289+ ret i32 %add
290+ }
291+
292+ define dso_local i64 @shladd64 (i64 %a , i64 %b ) local_unnamed_addr #0 {
293+ ; RV32IM-LABEL: shladd64:
294+ ; RV32IM: # %bb.0: # %entry
295+ ; RV32IM-NEXT: srli a4, a2, 1
296+ ; RV32IM-NEXT: slli a3, a3, 31
297+ ; RV32IM-NEXT: slli a2, a2, 31
298+ ; RV32IM-NEXT: or a3, a3, a4
299+ ; RV32IM-NEXT: add a0, a2, a0
300+ ; RV32IM-NEXT: sltu a2, a0, a2
301+ ; RV32IM-NEXT: add a1, a3, a1
302+ ; RV32IM-NEXT: add a1, a1, a2
303+ ; RV32IM-NEXT: ret
304+ ;
305+ ; RV32IMXQCIAC-LABEL: shladd64:
306+ ; RV32IMXQCIAC: # %bb.0: # %entry
307+ ; RV32IMXQCIAC-NEXT: srli a4, a2, 1
308+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a2, 31
309+ ; RV32IMXQCIAC-NEXT: slli a2, a2, 31
310+ ; RV32IMXQCIAC-NEXT: qc.shladd a3, a4, a3, 31
311+ ; RV32IMXQCIAC-NEXT: sltu a2, a0, a2
312+ ; RV32IMXQCIAC-NEXT: add a1, a1, a3
313+ ; RV32IMXQCIAC-NEXT: add a1, a1, a2
314+ ; RV32IMXQCIAC-NEXT: ret
315+ ;
316+ ; RV32IZBAMXQCIAC-LABEL: shladd64:
317+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
318+ ; RV32IZBAMXQCIAC-NEXT: srli a4, a2, 1
319+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a2, 31
320+ ; RV32IZBAMXQCIAC-NEXT: slli a2, a2, 31
321+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a3, a4, a3, 31
322+ ; RV32IZBAMXQCIAC-NEXT: sltu a2, a0, a2
323+ ; RV32IZBAMXQCIAC-NEXT: add a1, a1, a3
324+ ; RV32IZBAMXQCIAC-NEXT: add a1, a1, a2
325+ ; RV32IZBAMXQCIAC-NEXT: ret
326+ entry:
327+ %shl = shl nsw i64 %b , 31
328+ %add = add nsw i64 %shl , %a
329+ ret i64 %add
330+ }
331+
332+ define dso_local i32 @shladd_ordisjoint (i32 %a , i32 %b ) local_unnamed_addr #0 {
333+ ; RV32IM-LABEL: shladd_ordisjoint:
334+ ; RV32IM: # %bb.0: # %entry
335+ ; RV32IM-NEXT: slli a1, a1, 22
336+ ; RV32IM-NEXT: or a0, a1, a0
337+ ; RV32IM-NEXT: ret
338+ ;
339+ ; RV32IMXQCIAC-LABEL: shladd_ordisjoint:
340+ ; RV32IMXQCIAC: # %bb.0: # %entry
341+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a1, 22
342+ ; RV32IMXQCIAC-NEXT: ret
343+ ;
344+ ; RV32IZBAMXQCIAC-LABEL: shladd_ordisjoint:
345+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
346+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a1, 22
347+ ; RV32IZBAMXQCIAC-NEXT: ret
348+ entry:
349+ %shl = shl nsw i32 %b , 22
350+ %or = or disjoint i32 %shl , %a
351+ ret i32 %or
352+ }
353+
354+ define dso_local i32 @shladdc1c2 (i32 %a , i32 %b ) local_unnamed_addr #0 {
355+ ; RV32IM-LABEL: shladdc1c2:
356+ ; RV32IM: # %bb.0: # %entry
357+ ; RV32IM-NEXT: slli a0, a0, 31
358+ ; RV32IM-NEXT: slli a1, a1, 26
359+ ; RV32IM-NEXT: add a0, a0, a1
360+ ; RV32IM-NEXT: ret
361+ ;
362+ ; RV32IMXQCIAC-LABEL: shladdc1c2:
363+ ; RV32IMXQCIAC: # %bb.0: # %entry
364+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a1, a0, 5
365+ ; RV32IMXQCIAC-NEXT: slli a0, a0, 26
366+ ; RV32IMXQCIAC-NEXT: ret
367+ ;
368+ ; RV32IZBAMXQCIAC-LABEL: shladdc1c2:
369+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
370+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a1, a0, 5
371+ ; RV32IZBAMXQCIAC-NEXT: slli a0, a0, 26
372+ ; RV32IZBAMXQCIAC-NEXT: ret
373+ entry:
374+ %shlc1 = shl nsw i32 %a , 31
375+ %shlc2 = shl nsw i32 %b , 26
376+ %add = add nsw i32 %shlc1 , %shlc2
377+ ret i32 %add
378+ }
379+
380+ define dso_local i32 @shxaddc1c2 (i32 %a , i32 %b ) local_unnamed_addr #0 {
381+ ; RV32IM-LABEL: shxaddc1c2:
382+ ; RV32IM: # %bb.0: # %entry
383+ ; RV32IM-NEXT: slli a0, a0, 31
384+ ; RV32IM-NEXT: slli a1, a1, 28
385+ ; RV32IM-NEXT: add a0, a0, a1
386+ ; RV32IM-NEXT: ret
387+ ;
388+ ; RV32IMXQCIAC-LABEL: shxaddc1c2:
389+ ; RV32IMXQCIAC: # %bb.0: # %entry
390+ ; RV32IMXQCIAC-NEXT: slli a1, a1, 28
391+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a1, a0, 31
392+ ; RV32IMXQCIAC-NEXT: ret
393+ ;
394+ ; RV32IZBAMXQCIAC-LABEL: shxaddc1c2:
395+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
396+ ; RV32IZBAMXQCIAC-NEXT: sh3add a0, a0, a1
397+ ; RV32IZBAMXQCIAC-NEXT: slli a0, a0, 28
398+ ; RV32IZBAMXQCIAC-NEXT: ret
399+ entry:
400+ %shlc1 = shl nsw i32 %a , 31
401+ %shlc2 = shl nsw i32 %b , 28
402+ %add = add nsw i32 %shlc1 , %shlc2
403+ ret i32 %add
404+ }
405+
406+ define dso_local i64 @shladdc1c264 (i64 %a , i64 %b ) local_unnamed_addr #0 {
407+ ; RV32IM-LABEL: shladdc1c264:
408+ ; RV32IM: # %bb.0: # %entry
409+ ; RV32IM-NEXT: slli a1, a0, 23
410+ ; RV32IM-NEXT: srli a0, a2, 12
411+ ; RV32IM-NEXT: slli a3, a3, 20
412+ ; RV32IM-NEXT: or a3, a3, a0
413+ ; RV32IM-NEXT: slli a0, a2, 20
414+ ; RV32IM-NEXT: add a1, a1, a3
415+ ; RV32IM-NEXT: ret
416+ ;
417+ ; RV32IMXQCIAC-LABEL: shladdc1c264:
418+ ; RV32IMXQCIAC: # %bb.0: # %entry
419+ ; RV32IMXQCIAC-NEXT: srli a1, a2, 12
420+ ; RV32IMXQCIAC-NEXT: qc.shladd a1, a1, a3, 20
421+ ; RV32IMXQCIAC-NEXT: slli a2, a2, 20
422+ ; RV32IMXQCIAC-NEXT: qc.shladd a1, a1, a0, 23
423+ ; RV32IMXQCIAC-NEXT: mv a0, a2
424+ ; RV32IMXQCIAC-NEXT: ret
425+ ;
426+ ; RV32IZBAMXQCIAC-LABEL: shladdc1c264:
427+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
428+ ; RV32IZBAMXQCIAC-NEXT: srli a1, a2, 12
429+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a1, a1, a3, 20
430+ ; RV32IZBAMXQCIAC-NEXT: slli a2, a2, 20
431+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a1, a1, a0, 23
432+ ; RV32IZBAMXQCIAC-NEXT: mv a0, a2
433+ ; RV32IZBAMXQCIAC-NEXT: ret
434+ entry:
435+ %shlc1 = shl nsw i64 %a , 55
436+ %shlc2 = shl nsw i64 %b , 20
437+ %add = add nsw i64 %shlc1 , %shlc2
438+ ret i64 %add
439+ }
440+
441+ define dso_local i32 @shladdc1equalc2 (i32 %a , i32 %b ) local_unnamed_addr #0 {
442+ ; RV32IM-LABEL: shladdc1equalc2:
443+ ; RV32IM: # %bb.0: # %entry
444+ ; RV32IM-NEXT: slli a0, a0, 12
445+ ; RV32IM-NEXT: slli a1, a1, 12
446+ ; RV32IM-NEXT: add a0, a0, a1
447+ ; RV32IM-NEXT: ret
448+ ;
449+ ; RV32IMXQCIAC-LABEL: shladdc1equalc2:
450+ ; RV32IMXQCIAC: # %bb.0: # %entry
451+ ; RV32IMXQCIAC-NEXT: slli a1, a1, 12
452+ ; RV32IMXQCIAC-NEXT: qc.shladd a0, a1, a0, 12
453+ ; RV32IMXQCIAC-NEXT: ret
454+ ;
455+ ; RV32IZBAMXQCIAC-LABEL: shladdc1equalc2:
456+ ; RV32IZBAMXQCIAC: # %bb.0: # %entry
457+ ; RV32IZBAMXQCIAC-NEXT: slli a1, a1, 12
458+ ; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a1, a0, 12
459+ ; RV32IZBAMXQCIAC-NEXT: ret
460+ entry:
461+ %shlc1 = shl nsw i32 %a , 12
462+ %shlc2 = shl nsw i32 %b , 12
463+ %add = add nsw i32 %shlc1 , %shlc2
464+ ret i32 %add
465+ }
0 commit comments