brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · 5fad7f0 Raw
239 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "n8:16:32:64"5 6; Eliminating the casts in this testcase (by narrowing the AND operation)7; allows instcombine to realize the function always returns false.8 9define i1 @test1(i32 %A, i32 %B) {10; CHECK-LABEL: @test1(11; CHECK-NEXT:    ret i1 false12;13  %C1 = icmp slt i32 %A, %B14  %ELIM1 = zext i1 %C1 to i3215  %C2 = icmp sgt i32 %A, %B16  %ELIM2 = zext i1 %C2 to i3217  %C3 = and i32 %ELIM1, %ELIM218  %ELIM3 = trunc i32 %C3 to i119  ret i1 %ELIM320}21 22; The next 6 (3 logic ops * (scalar+vector)) tests show potential cases for narrowing a bitwise logic op.23 24define i32 @shrink_xor(i64 %a) {25; CHECK-LABEL: @shrink_xor(26; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i3227; CHECK-NEXT:    [[TRUNC:%.*]] = xor i32 [[TMP1]], 128; CHECK-NEXT:    ret i32 [[TRUNC]]29;30  %xor = xor i64 %a, 131  %trunc = trunc i64 %xor to i3232  ret i32 %trunc33}34 35; Vectors (with splat constants) should get the same transform.36 37define <2 x i32> @shrink_xor_vec(<2 x i64> %a) {38; CHECK-LABEL: @shrink_xor_vec(39; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>40; CHECK-NEXT:    [[TRUNC:%.*]] = xor <2 x i32> [[TMP1]], splat (i32 2)41; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]42;43  %xor = xor <2 x i64> %a, <i64 2, i64 2>44  %trunc = trunc <2 x i64> %xor to <2 x i32>45  ret <2 x i32> %trunc46}47 48; Source and dest types are not in the datalayout.49 50define i3 @shrink_or(i6 %a) {51; CHECK-LABEL: @shrink_or(52; CHECK-NEXT:    [[TMP1:%.*]] = trunc i6 [[A:%.*]] to i353; CHECK-NEXT:    [[TRUNC:%.*]] = or i3 [[TMP1]], 154; CHECK-NEXT:    ret i3 [[TRUNC]]55;56  %or = or i6 %a, 3357  %trunc = trunc i6 %or to i358  ret i3 %trunc59}60 61; Vectors (with non-splat constants) should get the same transform.62 63define <2 x i8> @shrink_or_vec(<2 x i16> %a) {64; CHECK-LABEL: @shrink_or_vec(65; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i16> [[A:%.*]] to <2 x i8>66; CHECK-NEXT:    [[TRUNC:%.*]] = or <2 x i8> [[TMP1]], <i8 -1, i8 0>67; CHECK-NEXT:    ret <2 x i8> [[TRUNC]]68;69  %or = or <2 x i16> %a, <i16 -1, i16 256>70  %trunc = trunc <2 x i16> %or to <2 x i8>71  ret <2 x i8> %trunc72}73 74; We discriminate against weird types.75 76define i31 @shrink_and(i64 %a) {77; CHECK-LABEL: @shrink_and(78; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A:%.*]], 4279; CHECK-NEXT:    [[TRUNC:%.*]] = trunc nuw nsw i64 [[AND]] to i3180; CHECK-NEXT:    ret i31 [[TRUNC]]81;82  %and = and i64 %a, 4283  %trunc = trunc i64 %and to i3184  ret i31 %trunc85}86 87; Chop the top of the constant(s) if needed.88 89define <2 x i32> @shrink_and_vec(<2 x i33> %a) {90; CHECK-LABEL: @shrink_and_vec(91; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i33> [[A:%.*]] to <2 x i32>92; CHECK-NEXT:    [[TRUNC:%.*]] = and <2 x i32> [[TMP1]], <i32 0, i32 6>93; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]94;95  %and = and <2 x i33> %a, <i33 4294967296, i33 6>96  %trunc = trunc <2 x i33> %and to <2 x i32>97  ret <2 x i32> %trunc98}99 100; FIXME:101; This is based on an 'any_of' loop construct.102; By narrowing the phi and logic op, we simplify away the zext and the final icmp.103 104define i1 @searchArray1(i32 %needle, ptr %haystack) {105; CHECK-LABEL: @searchArray1(106; CHECK-NEXT:  entry:107; CHECK-NEXT:    br label [[LOOP:%.*]]108; CHECK:       loop:109; CHECK-NEXT:    [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[LOOP]] ]110; CHECK-NEXT:    [[FOUND:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[OR:%.*]], [[LOOP]] ]111; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[INDVAR]] to i64112; CHECK-NEXT:    [[IDX:%.*]] = getelementptr i32, ptr [[HAYSTACK:%.*]], i64 [[TMP0]]113; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[IDX]], align 4114; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[LD]], [[NEEDLE:%.*]]115; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP1]] to i8116; CHECK-NEXT:    [[OR]] = or i8 [[FOUND]], [[ZEXT]]117; CHECK-NEXT:    [[INDVAR_NEXT]] = add i32 [[INDVAR]], 1118; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INDVAR_NEXT]], 1000119; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]120; CHECK:       exit:121; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[OR]], 0122; CHECK-NEXT:    ret i1 [[TOBOOL]]123;124entry:125  br label %loop126 127loop:128  %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %loop ]129  %found = phi i8 [ 0, %entry ], [ %or, %loop ]130  %idx = getelementptr i32, ptr %haystack, i32 %indvar131  %ld = load i32, ptr %idx132  %cmp1 = icmp eq i32 %ld, %needle133  %zext = zext i1 %cmp1 to i8134  %or = or i8 %found, %zext135  %indvar.next = add i32 %indvar, 1136  %exitcond = icmp eq i32 %indvar.next, 1000137  br i1 %exitcond, label %exit, label %loop138 139exit:140  %tobool = icmp ne i8 %or, 0141  ret i1 %tobool142}143 144; FIXME:145; This is based on an 'all_of' loop construct.146; By narrowing the phi and logic op, we simplify away the zext and the final icmp.147 148define i1 @searchArray2(i32 %hay, ptr %haystack) {149; CHECK-LABEL: @searchArray2(150; CHECK-NEXT:  entry:151; CHECK-NEXT:    br label [[LOOP:%.*]]152; CHECK:       loop:153; CHECK-NEXT:    [[INDVAR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[LOOP]] ]154; CHECK-NEXT:    [[FOUND:%.*]] = phi i8 [ 1, [[ENTRY]] ], [ [[AND:%.*]], [[LOOP]] ]155; CHECK-NEXT:    [[IDX:%.*]] = getelementptr i32, ptr [[HAYSTACK:%.*]], i64 [[INDVAR]]156; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[IDX]], align 4157; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[LD]], [[HAY:%.*]]158; CHECK-NEXT:    [[AND]] = select i1 [[CMP1]], i8 [[FOUND]], i8 0159; CHECK-NEXT:    [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1160; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], 1000161; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]162; CHECK:       exit:163; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0164; CHECK-NEXT:    ret i1 [[TOBOOL]]165;166entry:167  br label %loop168 169loop:170  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]171  %found = phi i8 [ 1, %entry ], [ %and, %loop ]172  %idx = getelementptr i32, ptr %haystack, i64 %indvar173  %ld = load i32, ptr %idx174  %cmp1 = icmp eq i32 %ld, %hay175  %zext = zext i1 %cmp1 to i8176  %and = and i8 %found, %zext177  %indvar.next = add i64 %indvar, 1178  %exitcond = icmp eq i64 %indvar.next, 1000179  br i1 %exitcond, label %exit, label %loop180 181exit:182  %tobool = icmp ne i8 %and, 0183  ret i1 %tobool184}185 186; FIXME:187; Narrowing should work with an 'xor' and is not limited to bool types.188 189define i32 @shrinkLogicAndPhi1(i8 %x, i1 %cond) {190; CHECK-LABEL: @shrinkLogicAndPhi1(191; CHECK-NEXT:  entry:192; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ENDIF:%.*]]193; CHECK:       if:194; CHECK-NEXT:    br label [[ENDIF]]195; CHECK:       endif:196; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 21, [[ENTRY:%.*]] ], [ 33, [[IF]] ]197; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32198; CHECK-NEXT:    [[LOGIC:%.*]] = xor i32 [[PHI]], [[ZEXT]]199; CHECK-NEXT:    ret i32 [[LOGIC]]200;201entry:202  br i1 %cond, label %if, label %endif203if:204  br label %endif205endif:206  %phi = phi i32 [ 21, %entry], [ 33, %if ]207  %zext = zext i8 %x to i32208  %logic = xor i32 %phi, %zext209  ret i32 %logic210}211 212; FIXME:213; Narrowing should work with an 'xor' and is not limited to bool types.214; Test that commuting the xor operands does not inhibit optimization.215 216define i32 @shrinkLogicAndPhi2(i8 %x, i1 %cond) {217; CHECK-LABEL: @shrinkLogicAndPhi2(218; CHECK-NEXT:  entry:219; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ENDIF:%.*]]220; CHECK:       if:221; CHECK-NEXT:    br label [[ENDIF]]222; CHECK:       endif:223; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 21, [[ENTRY:%.*]] ], [ 33, [[IF]] ]224; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32225; CHECK-NEXT:    [[LOGIC:%.*]] = xor i32 [[PHI]], [[ZEXT]]226; CHECK-NEXT:    ret i32 [[LOGIC]]227;228entry:229  br i1 %cond, label %if, label %endif230if:231  br label %endif232endif:233  %phi = phi i32 [ 21, %entry], [ 33, %if ]234  %zext = zext i8 %x to i32235  %logic = xor i32 %zext, %phi236  ret i32 %logic237}238 239