1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; Fold 5; x - ((x / y) * y) 6; to 7; x % y 8 9; Also, 10; ((x / y) * y) 11; can then be simplified to 12; x - (x % y) 13 14declare void @use8(i8) 15declare void @use2xi8(<2 x i8>) 16 17define i8 @t0_basic(i8 %x, i8 %y) { 18; CHECK-LABEL: @t0_basic( 19; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 20; CHECK-NEXT: call void @use8(i8 [[DIV]]) 21; CHECK-NEXT: [[ROUNDXDOWNTOMULTIPLEOFY:%.*]] = mul i8 [[DIV]], [[Y]] 22; CHECK-NEXT: [[REM:%.*]] = sub i8 [[X]], [[ROUNDXDOWNTOMULTIPLEOFY]] 23; CHECK-NEXT: ret i8 [[REM]] 24; 25 %div = udiv i8 %x, %y 26 call void @use8(i8 %div) 27 %roundXdownToMultipleOfY = mul i8 %div, %y 28 %rem = sub i8 %x, %roundXdownToMultipleOfY 29 ret i8 %rem 30} 31 32define <2 x i8> @t1_vector(<2 x i8> %x, <2 x i8> %y) { 33; CHECK-LABEL: @t1_vector( 34; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]] 35; CHECK-NEXT: call void @use2xi8(<2 x i8> [[DIV]]) 36; CHECK-NEXT: [[ROUNDXDOWNTOMULTIPLEOFY:%.*]] = mul <2 x i8> [[DIV]], [[Y]] 37; CHECK-NEXT: [[REM:%.*]] = sub <2 x i8> [[X]], [[ROUNDXDOWNTOMULTIPLEOFY]] 38; CHECK-NEXT: ret <2 x i8> [[REM]] 39; 40 %div = udiv <2 x i8> %x, %y 41 call void @use2xi8(<2 x i8> %div) 42 %roundXdownToMultipleOfY = mul <2 x i8> %div, %y 43 %rem = sub <2 x i8> %x, %roundXdownToMultipleOfY 44 ret <2 x i8> %rem 45} 46 47; Extra use 48 49define i8 @t4_extrause(i8 %x, i8 %y) { 50; CHECK-LABEL: @t4_extrause( 51; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]] 52; CHECK-NEXT: call void @use8(i8 [[DIV]]) 53; CHECK-NEXT: [[ROUNDXDOWNTOMULTIPLEOFY:%.*]] = mul i8 [[DIV]], [[Y]] 54; CHECK-NEXT: call void @use8(i8 [[ROUNDXDOWNTOMULTIPLEOFY]]) 55; CHECK-NEXT: [[REM:%.*]] = sub i8 [[X]], [[ROUNDXDOWNTOMULTIPLEOFY]] 56; CHECK-NEXT: ret i8 [[REM]] 57; 58 %div = udiv i8 %x, %y 59 call void @use8(i8 %div) 60 %roundXdownToMultipleOfY = mul i8 %div, %y 61 call void @use8(i8 %roundXdownToMultipleOfY) 62 %rem = sub i8 %x, %roundXdownToMultipleOfY 63 ret i8 %rem 64} 65 66; Commutativity 67 68declare i8 @gen8() 69 70define i8 @t5_commutative(i8 %x) { 71; CHECK-LABEL: @t5_commutative( 72; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8() 73; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X:%.*]], [[Y]] 74; CHECK-NEXT: call void @use8(i8 [[DIV]]) 75; CHECK-NEXT: [[ROUNDXDOWNTOMULTIPLEOFY:%.*]] = mul i8 [[Y]], [[DIV]] 76; CHECK-NEXT: [[REM:%.*]] = sub i8 [[X]], [[ROUNDXDOWNTOMULTIPLEOFY]] 77; CHECK-NEXT: ret i8 [[REM]] 78; 79 %y = call i8 @gen8() 80 %div = udiv i8 %x, %y 81 call void @use8(i8 %div) 82 %roundXdownToMultipleOfY = mul i8 %y, %div ; swapped 83 %rem = sub i8 %x, %roundXdownToMultipleOfY 84 ret i8 %rem 85} 86 87; Negative tests 88 89define i8 @n6_different_x(i8 %x0, i8 %x1, i8 %y) { 90; CHECK-LABEL: @n6_different_x( 91; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X0:%.*]], [[Y:%.*]] 92; CHECK-NEXT: call void @use8(i8 [[DIV]]) 93; CHECK-NEXT: [[ROUNDXDOWNTOMULTIPLEOFY:%.*]] = mul i8 [[DIV]], [[Y]] 94; CHECK-NEXT: [[REM:%.*]] = sub i8 [[X1:%.*]], [[ROUNDXDOWNTOMULTIPLEOFY]] 95; CHECK-NEXT: ret i8 [[REM]] 96; 97 %div = udiv i8 %x0, %y 98 call void @use8(i8 %div) 99 %roundXdownToMultipleOfY = mul i8 %div, %y 100 %rem = sub i8 %x1, %roundXdownToMultipleOfY 101 ret i8 %rem 102} 103 104define i8 @n6_different_y(i8 %x, i8 %y0, i8 %y1) { 105; CHECK-LABEL: @n6_different_y( 106; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X:%.*]], [[Y0:%.*]] 107; CHECK-NEXT: call void @use8(i8 [[DIV]]) 108; CHECK-NEXT: [[ROUNDXDOWNTOMULTIPLEOFY:%.*]] = mul i8 [[DIV]], [[Y1:%.*]] 109; CHECK-NEXT: [[REM:%.*]] = sub i8 [[X]], [[ROUNDXDOWNTOMULTIPLEOFY]] 110; CHECK-NEXT: ret i8 [[REM]] 111; 112 %div = udiv i8 %x, %y0 113 call void @use8(i8 %div) 114 %roundXdownToMultipleOfY = mul i8 %div, %y1 115 %rem = sub i8 %x, %roundXdownToMultipleOfY 116 ret i8 %rem 117} 118