@@ -343,3 +343,133 @@ define i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {
343343 %r = select i1 %gt , i8 1 , i8 %lt
344344 ret i8 %r
345345}
346+
347+ ; (x == y) ? 0 : (x s> y ? 1 : -1) into scmp(x, y)
348+ define i8 @scmp_from_select_eq_and_gt (i32 %x , i32 %y ) {
349+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
350+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
351+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
352+ ; CHECK-NEXT: ret i8 [[R]]
353+ ;
354+ %eq = icmp eq i32 %x , %y
355+ %gt = icmp sgt i32 %x , %y
356+ %sel1 = select i1 %gt , i8 1 , i8 -1
357+ %r = select i1 %eq , i8 0 , i8 %sel1
358+ ret i8 %r
359+ }
360+
361+ define i8 @scmp_from_select_eq_and_gt_inverse (i32 %x , i32 %y ) {
362+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_inverse(
363+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
364+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
365+ ; CHECK-NEXT: ret i8 [[R]]
366+ ;
367+ %ne = icmp ne i32 %x , %y
368+ %gt = icmp sgt i32 %x , %y
369+ %sel1 = select i1 %gt , i8 1 , i8 -1
370+ %r = select i1 %ne , i8 %sel1 , i8 0
371+ ret i8 %r
372+ }
373+
374+ define <4 x i8 > @scmp_from_select_eq_and_gt_vec (<4 x i32 > %x , <4 x i32 > %y ) {
375+ ; CHECK-LABEL: define <4 x i8> @scmp_from_select_eq_and_gt_vec(
376+ ; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
377+ ; CHECK-NEXT: [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
378+ ; CHECK-NEXT: ret <4 x i8> [[R]]
379+ ;
380+ %eq = icmp eq <4 x i32 > %x , %y
381+ %gt = icmp sgt <4 x i32 > %x , %y
382+ %sel1 = select <4 x i1 > %gt , <4 x i8 > splat(i8 1 ), <4 x i8 > splat(i8 -1 )
383+ %r = select <4 x i1 > %eq , <4 x i8 > splat(i8 0 ), <4 x i8 > %sel1
384+ ret <4 x i8 > %r
385+ }
386+
387+ define i8 @scmp_from_select_eq_and_gt_commuted1 (i32 %x , i32 %y ) {
388+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(
389+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
390+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
391+ ; CHECK-NEXT: ret i8 [[R]]
392+ ;
393+ %eq = icmp eq i32 %x , %y
394+ %gt = icmp slt i32 %x , %y
395+ %sel1 = select i1 %gt , i8 1 , i8 -1
396+ %r = select i1 %eq , i8 0 , i8 %sel1
397+ ret i8 %r
398+ }
399+
400+ define i8 @scmp_from_select_eq_and_gt_commuted2 (i32 %x , i32 %y ) {
401+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(
402+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
403+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
404+ ; CHECK-NEXT: ret i8 [[R]]
405+ ;
406+ %eq = icmp eq i32 %x , %y
407+ %gt = icmp sgt i32 %x , %y
408+ %sel1 = select i1 %gt , i8 -1 , i8 1
409+ %r = select i1 %eq , i8 0 , i8 %sel1
410+ ret i8 %r
411+ }
412+
413+ define i8 @scmp_from_select_eq_and_gt_commuted3 (i32 %x , i32 %y ) {
414+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(
415+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
416+ ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
417+ ; CHECK-NEXT: ret i8 [[R]]
418+ ;
419+ %eq = icmp eq i32 %x , %y
420+ %gt = icmp slt i32 %x , %y
421+ %sel1 = select i1 %gt , i8 -1 , i8 1
422+ %r = select i1 %eq , i8 0 , i8 %sel1
423+ ret i8 %r
424+ }
425+
426+ ; Negative test: true value of outer select is not zero
427+ define i8 @scmp_from_select_eq_and_gt_neg1 (i32 %x , i32 %y ) {
428+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
429+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
430+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
431+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
432+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
433+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 5, i8 [[SEL1]]
434+ ; CHECK-NEXT: ret i8 [[R]]
435+ ;
436+ %eq = icmp eq i32 %x , %y
437+ %gt = icmp sgt i32 %x , %y
438+ %sel1 = select i1 %gt , i8 1 , i8 -1
439+ %r = select i1 %eq , i8 5 , i8 %sel1
440+ ret i8 %r
441+ }
442+
443+ ; Negative test: true value of inner select is not 1 or -1
444+ define i8 @scmp_from_select_eq_and_gt_neg2 (i32 %x , i32 %y ) {
445+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg2(
446+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
447+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
448+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
449+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 2, i8 -1
450+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
451+ ; CHECK-NEXT: ret i8 [[R]]
452+ ;
453+ %eq = icmp eq i32 %x , %y
454+ %gt = icmp sgt i32 %x , %y
455+ %sel1 = select i1 %gt , i8 2 , i8 -1
456+ %r = select i1 %eq , i8 0 , i8 %sel1
457+ ret i8 %r
458+ }
459+
460+ ; Negative test: false value of inner select is not 1 or -1
461+ define i8 @scmp_from_select_eq_and_gt_neg3 (i32 %x , i32 %y ) {
462+ ; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg3(
463+ ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
464+ ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
465+ ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
466+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 22
467+ ; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
468+ ; CHECK-NEXT: ret i8 [[R]]
469+ ;
470+ %eq = icmp eq i32 %x , %y
471+ %gt = icmp sgt i32 %x , %y
472+ %sel1 = select i1 %gt , i8 1 , i8 22
473+ %r = select i1 %eq , i8 0 , i8 %sel1
474+ ret i8 %r
475+ }
0 commit comments