174 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Fold5; ((ptr %y) s/ %x) == %y6; to7; @llvm.smul.with.overflow(%x, %y) + extractvalue + not8 9define i1 @t0_basic(i8 %x, i8 %y) {10; CHECK-LABEL: @t0_basic(11; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])12; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i8, i1 } [[MUL]], 113; CHECK-NEXT: [[MUL_NOT_OV:%.*]] = xor i1 [[MUL_OV]], true14; CHECK-NEXT: ret i1 [[MUL_NOT_OV]]15;16 %t0 = mul i8 %x, %y17 %t1 = sdiv i8 %t0, %x18 %r = icmp eq i8 %t1, %y19 ret i1 %r20}21 22define <2 x i1> @t1_vec(<2 x i8> %x, <2 x i8> %y) {23; CHECK-LABEL: @t1_vec(24; CHECK-NEXT: [[MUL:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.smul.with.overflow.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]])25; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[MUL]], 126; CHECK-NEXT: [[MUL_NOT_OV:%.*]] = xor <2 x i1> [[MUL_OV]], splat (i1 true)27; CHECK-NEXT: ret <2 x i1> [[MUL_NOT_OV]]28;29 %t0 = mul <2 x i8> %x, %y30 %t1 = sdiv <2 x i8> %t0, %x31 %r = icmp eq <2 x i8> %t1, %y32 ret <2 x i1> %r33}34 35declare i8 @gen8()36 37define i1 @t2_commutative(i8 %x) {38; CHECK-LABEL: @t2_commutative(39; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8()40; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 [[Y]])41; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i8, i1 } [[MUL]], 142; CHECK-NEXT: [[MUL_NOT_OV:%.*]] = xor i1 [[MUL_OV]], true43; CHECK-NEXT: ret i1 [[MUL_NOT_OV]]44;45 %y = call i8 @gen8()46 %t0 = mul i8 %y, %x ; swapped47 %t1 = sdiv i8 %t0, %x48 %r = icmp eq i8 %t1, %y49 ret i1 %r50}51 52define i1 @t3_commutative(i8 %x) {53; CHECK-LABEL: @t3_commutative(54; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8()55; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 [[Y]])56; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i8, i1 } [[MUL]], 157; CHECK-NEXT: [[MUL_NOT_OV:%.*]] = xor i1 [[MUL_OV]], true58; CHECK-NEXT: ret i1 [[MUL_NOT_OV]]59;60 %y = call i8 @gen8()61 %t0 = mul i8 %y, %x ; swapped62 %t1 = sdiv i8 %t0, %x63 %r = icmp eq i8 %t1, %y64 ret i1 %r65}66 67define i1 @t4_commutative(i8 %x) {68; CHECK-LABEL: @t4_commutative(69; CHECK-NEXT: [[Y:%.*]] = call i8 @gen8()70; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 [[Y]])71; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i8, i1 } [[MUL]], 172; CHECK-NEXT: [[MUL_NOT_OV:%.*]] = xor i1 [[MUL_OV]], true73; CHECK-NEXT: ret i1 [[MUL_NOT_OV]]74;75 %y = call i8 @gen8()76 %t0 = mul i8 %y, %x ; swapped77 %t1 = sdiv i8 %t0, %x78 %r = icmp eq i8 %y, %t1 ; swapped79 ret i1 %r80}81 82; Extra-use tests83 84declare void @use8(i8)85 86define i1 @t5_extrause0(i8 %x, i8 %y) {87; CHECK-LABEL: @t5_extrause0(88; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[X:%.*]], i8 [[Y:%.*]])89; CHECK-NEXT: [[MUL_VAL:%.*]] = extractvalue { i8, i1 } [[MUL]], 090; CHECK-NEXT: [[MUL_OV:%.*]] = extractvalue { i8, i1 } [[MUL]], 191; CHECK-NEXT: [[MUL_NOT_OV:%.*]] = xor i1 [[MUL_OV]], true92; CHECK-NEXT: call void @use8(i8 [[MUL_VAL]])93; CHECK-NEXT: ret i1 [[MUL_NOT_OV]]94;95 %t0 = mul i8 %x, %y96 call void @use8(i8 %t0)97 %t1 = sdiv i8 %t0, %x98 %r = icmp eq i8 %t1, %y99 ret i1 %r100}101 102define i1 @t6_extrause1(i8 %x, i8 %y) {103; CHECK-LABEL: @t6_extrause1(104; CHECK-NEXT: [[T0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]105; CHECK-NEXT: [[T1:%.*]] = sdiv i8 [[T0]], [[X]]106; CHECK-NEXT: call void @use8(i8 [[T1]])107; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[T1]], [[Y]]108; CHECK-NEXT: ret i1 [[R]]109;110 %t0 = mul i8 %x, %y111 %t1 = sdiv i8 %t0, %x112 call void @use8(i8 %t1)113 %r = icmp eq i8 %t1, %y114 ret i1 %r115}116 117define i1 @t7_extrause2(i8 %x, i8 %y) {118; CHECK-LABEL: @t7_extrause2(119; CHECK-NEXT: [[T0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]120; CHECK-NEXT: call void @use8(i8 [[T0]])121; CHECK-NEXT: [[T1:%.*]] = sdiv i8 [[T0]], [[X]]122; CHECK-NEXT: call void @use8(i8 [[T1]])123; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[T1]], [[Y]]124; CHECK-NEXT: ret i1 [[R]]125;126 %t0 = mul i8 %x, %y127 call void @use8(i8 %t0)128 %t1 = sdiv i8 %t0, %x129 call void @use8(i8 %t1)130 %r = icmp eq i8 %t1, %y131 ret i1 %r132}133 134; Negative tests135 136define i1 @n8_different_x(i8 %x0, i8 %x1, i8 %y) {137; CHECK-LABEL: @n8_different_x(138; CHECK-NEXT: [[T0:%.*]] = mul i8 [[X0:%.*]], [[Y:%.*]]139; CHECK-NEXT: [[T1:%.*]] = sdiv i8 [[T0]], [[X1:%.*]]140; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[T1]], [[Y]]141; CHECK-NEXT: ret i1 [[R]]142;143 %t0 = mul i8 %x0, %y144 %t1 = sdiv i8 %t0, %x1145 %r = icmp eq i8 %t1, %y146 ret i1 %r147}148 149define i1 @n9_different_y(i8 %x, i8 %y0, i8 %y1) {150; CHECK-LABEL: @n9_different_y(151; CHECK-NEXT: [[T0:%.*]] = mul i8 [[X:%.*]], [[Y0:%.*]]152; CHECK-NEXT: [[T1:%.*]] = sdiv i8 [[T0]], [[X]]153; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[T1]], [[Y1:%.*]]154; CHECK-NEXT: ret i1 [[R]]155;156 %t0 = mul i8 %x, %y0157 %t1 = sdiv i8 %t0, %x158 %r = icmp eq i8 %t1, %y1159 ret i1 %r160}161 162define i1 @n10_wrong_pred(i8 %x, i8 %y) {163; CHECK-LABEL: @n10_wrong_pred(164; CHECK-NEXT: [[T0:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]165; CHECK-NEXT: [[T1:%.*]] = sdiv i8 [[T0]], [[X]]166; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T1]], [[Y]]167; CHECK-NEXT: ret i1 [[R]]168;169 %t0 = mul i8 %x, %y170 %t1 = sdiv i8 %t0, %x171 %r = icmp ult i8 %t1, %y172 ret i1 %r173}174