181 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Test known bits refinements for pattern: a * (b - c) + c * d5; where a > 0, c > 0, b > 0, d > 0, and b > c.6; This pattern is a generalization of lerp and it appears frequently in graphics operations.7 8define i32 @test_clamp(i8 %a, i8 %c, i8 %d) {9; CHECK-LABEL: define i32 @test_clamp(10; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {11; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i3212; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i3213; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i3214; CHECK-NEXT: [[SUB:%.*]] = xor i32 [[C32]], 25515; CHECK-NEXT: [[MUL1:%.*]] = mul nuw nsw i32 [[SUB]], [[A32]]16; CHECK-NEXT: [[MUL2:%.*]] = mul nuw nsw i32 [[C32]], [[D32]]17; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[MUL1]], [[MUL2]]18; CHECK-NEXT: ret i32 [[ADD]]19;20 %a32 = zext i8 %a to i3221 %c32 = zext i8 %c to i3222 %d32 = zext i8 %d to i3223 %sub = sub i32 255, %c3224 %mul1 = mul i32 %a32, %sub25 %mul2 = mul i32 %c32, %d3226 %add = add i32 %mul1, %mul227 %cmp = icmp ugt i32 %add, 6553528 %result = select i1 %cmp, i32 65535, i32 %add29 ret i32 %result30}31 32define i1 @test_trunc_cmp(i8 %a, i8 %c, i8 %d) {33; CHECK-LABEL: define i1 @test_trunc_cmp(34; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {35; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i1636; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i1637; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i1638; CHECK-NEXT: [[SUB:%.*]] = xor i16 [[C32]], 25539; CHECK-NEXT: [[MUL1:%.*]] = mul nuw i16 [[SUB]], [[A32]]40; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i16 [[C32]], [[D32]]41; CHECK-NEXT: [[ADD:%.*]] = add i16 [[MUL1]], [[MUL2]]42; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ADD]], 123443; CHECK-NEXT: ret i1 [[CMP]]44;45 %a32 = zext i8 %a to i3246 %c32 = zext i8 %c to i3247 %d32 = zext i8 %d to i3248 %sub = sub i32 255, %c3249 %mul1 = mul i32 %a32, %sub50 %mul2 = mul i32 %c32, %d3251 %add = add i32 %mul1, %mul252 %trunc = trunc i32 %add to i1653 %cmp = icmp eq i16 %trunc, 123454 ret i1 %cmp55}56 57define i1 @test_trunc_cmp_xor(i8 %a, i8 %c, i8 %d) {58; CHECK-LABEL: define i1 @test_trunc_cmp_xor(59; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {60; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i1661; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i1662; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i1663; CHECK-NEXT: [[SUB:%.*]] = xor i16 [[C32]], 25564; CHECK-NEXT: [[MUL1:%.*]] = mul nuw i16 [[SUB]], [[A32]]65; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i16 [[C32]], [[D32]]66; CHECK-NEXT: [[ADD:%.*]] = add i16 [[MUL1]], [[MUL2]]67; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ADD]], 123468; CHECK-NEXT: ret i1 [[CMP]]69;70 %a32 = zext i8 %a to i3271 %c32 = zext i8 %c to i3272 %d32 = zext i8 %d to i3273 %sub = xor i32 255, %c3274 %mul1 = mul i32 %a32, %sub75 %mul2 = mul i32 %c32, %d3276 %add = add i32 %mul1, %mul277 %trunc = trunc i32 %add to i1678 %cmp = icmp eq i16 %trunc, 123479 ret i1 %cmp80}81 82define i1 @test_trunc_cmp_arbitrary_b(i8 %a, i8 %b, i8 %c, i8 %d) {83; CHECK-LABEL: define i1 @test_trunc_cmp_arbitrary_b(84; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {85; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i1686; CHECK-NEXT: [[B32:%.*]] = zext i8 [[B]] to i1687; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i1688; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i1689; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[B32]], [[C32]]90; CHECK-NEXT: [[MUL1:%.*]] = mul i16 [[SUB]], [[A32]]91; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i16 [[C32]], [[D32]]92; CHECK-NEXT: [[ADD:%.*]] = add i16 [[MUL1]], [[MUL2]]93; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ADD]], 123494; CHECK-NEXT: ret i1 [[CMP]]95;96 %a32 = zext i8 %a to i3297 %b32 = zext i8 %b to i3298 %c32 = zext i8 %c to i3299 %d32 = zext i8 %d to i32100 %sub = sub nsw nuw i32 %b32, %c32101 %mul1 = mul i32 %a32, %sub102 %mul2 = mul i32 %c32, %d32103 %add = add i32 %mul1, %mul2104 %trunc = trunc i32 %add to i16105 %cmp = icmp eq i16 %trunc, 1234106 ret i1 %cmp107}108 109 110define i1 @test_trunc_cmp_no_a(i8 %b, i8 %c, i8 %d) {111; CHECK-LABEL: define i1 @test_trunc_cmp_no_a(112; CHECK-SAME: i8 [[B:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {113; CHECK-NEXT: [[B32:%.*]] = zext i8 [[B]] to i16114; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i16115; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i16116; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[B32]], [[C32]]117; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i16 [[C32]], [[D32]]118; CHECK-NEXT: [[ADD:%.*]] = add i16 [[SUB]], [[MUL2]]119; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ADD]], 1234120; CHECK-NEXT: ret i1 [[CMP]]121;122 %b32 = zext i8 %b to i32123 %c32 = zext i8 %c to i32124 %d32 = zext i8 %d to i32125 %sub = sub nuw i32 %b32, %c32126 %mul2 = mul i32 %c32, %d32127 %add = add i32 %sub, %mul2128 %trunc = trunc i32 %add to i16129 %cmp = icmp eq i16 %trunc, 1234130 ret i1 %cmp131}132 133define i1 @test_trunc_cmp_no_d(i8 %a, i8 %b, i8 %c) {134; CHECK-LABEL: define i1 @test_trunc_cmp_no_d(135; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) {136; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i16137; CHECK-NEXT: [[B32:%.*]] = zext i8 [[B]] to i16138; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i16139; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[B32]], [[C32]]140; CHECK-NEXT: [[MUL1:%.*]] = mul i16 [[SUB]], [[A32]]141; CHECK-NEXT: [[ADD:%.*]] = add i16 [[MUL1]], [[C32]]142; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[ADD]], 1234143; CHECK-NEXT: ret i1 [[CMP]]144;145 %a32 = zext i8 %a to i32146 %b32 = zext i8 %b to i32147 %c32 = zext i8 %c to i32148 %sub = sub nsw nuw i32 %b32, %c32149 %mul1 = mul i32 %a32, %sub150 %add = add i32 %mul1, %c32151 %trunc = trunc i32 %add to i16152 %cmp = icmp eq i16 %trunc, 1234153 ret i1 %cmp154}155 156define i1 @test_trunc_cmp_xor_negative(i8 %a, i8 %c, i8 %d) {157; CHECK-LABEL: define i1 @test_trunc_cmp_xor_negative(158; CHECK-SAME: i8 [[A:%.*]], i8 [[C:%.*]], i8 [[D:%.*]]) {159; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i16160; CHECK-NEXT: [[C32:%.*]] = zext i8 [[C]] to i16161; CHECK-NEXT: [[D32:%.*]] = zext i8 [[D]] to i16162; CHECK-NEXT: [[SUB:%.*]] = xor i16 [[C32]], 234163; CHECK-NEXT: [[MUL1:%.*]] = mul nuw i16 [[SUB]], [[A32]]164; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i16 [[C32]], [[D32]]165; CHECK-NEXT: [[TRUNC:%.*]] = add i16 [[MUL1]], [[MUL2]]166; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TRUNC]], 1234167; CHECK-NEXT: ret i1 [[CMP]]168;169 %a32 = zext i8 %a to i32170 %c32 = zext i8 %c to i32171 %d32 = zext i8 %d to i32172 %sub = xor i32 234, %c32173 %mul1 = mul i32 %a32, %sub174 %mul2 = mul i32 %c32, %d32175 %add = add i32 %mul1, %mul2176 ; We should keep the trunc in this case177 %trunc = trunc i32 %add to i16178 %cmp = icmp eq i16 %trunc, 1234179 ret i1 %cmp180}181