brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · abae2c6 Raw
339 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Given pattern:5;   (x shiftopcode Q) shiftopcode K6; we should rewrite it as7;   x shiftopcode (Q+K)  iff (Q+K) u< bitwidth(x)8; This is valid for any shift, but they must be identical.9; THIS FOLD DOES *NOT* REQUIRE ANY 'exact'/'nuw'/`nsw` FLAGS!10 11; Basic scalar test12 13define i32 @t0(i32 %x, i32 %y) {14; CHECK-LABEL: @t0(15; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[X:%.*]], 3016; CHECK-NEXT:    ret i32 [[T3]]17;18  %t0 = sub i32 32, %y19  %t1 = lshr i32 %x, %t020  %t2 = add i32 %y, -221  %t3 = lshr exact i32 %t1, %t2 ; while there, test that we don't propagate partial 'exact' flag22  ret i32 %t323}24 25define <2 x i32> @t1_vec_splat(<2 x i32> %x, <2 x i32> %y) {26; CHECK-LABEL: @t1_vec_splat(27; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 30)28; CHECK-NEXT:    ret <2 x i32> [[T3]]29;30  %t0 = sub <2 x i32> <i32 32, i32 32>, %y31  %t1 = lshr <2 x i32> %x, %t032  %t2 = add <2 x i32> %y, <i32 -2, i32 -2>33  %t3 = lshr <2 x i32> %t1, %t234  ret <2 x i32> %t335}36 37define <2 x i32> @t2_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {38; CHECK-LABEL: @t2_vec_nonsplat(39; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 30)40; CHECK-NEXT:    ret <2 x i32> [[T3]]41;42  %t0 = sub <2 x i32> <i32 32, i32 30>, %y43  %t1 = lshr <2 x i32> %x, %t044  %t2 = add <2 x i32> %y, <i32 -2, i32 0>45  %t3 = lshr <2 x i32> %t1, %t246  ret <2 x i32> %t347}48 49; Basic vector tests50 51define <3 x i32> @t3_vec_nonsplat_poison0(<3 x i32> %x, <3 x i32> %y) {52; CHECK-LABEL: @t3_vec_nonsplat_poison0(53; CHECK-NEXT:    [[T3:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 30, i32 poison, i32 30>54; CHECK-NEXT:    ret <3 x i32> [[T3]]55;56  %t0 = sub <3 x i32> <i32 32, i32 poison, i32 32>, %y57  %t1 = lshr <3 x i32> %x, %t058  %t2 = add <3 x i32> %y, <i32 -2, i32 -2, i32 -2>59  %t3 = lshr <3 x i32> %t1, %t260  ret <3 x i32> %t361}62 63define <3 x i32> @t4_vec_nonsplat_poison1(<3 x i32> %x, <3 x i32> %y) {64; CHECK-LABEL: @t4_vec_nonsplat_poison1(65; CHECK-NEXT:    [[T3:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 30, i32 poison, i32 30>66; CHECK-NEXT:    ret <3 x i32> [[T3]]67;68  %t0 = sub <3 x i32> <i32 32, i32 32, i32 32>, %y69  %t1 = lshr <3 x i32> %x, %t070  %t2 = add <3 x i32> %y, <i32 -2, i32 poison, i32 -2>71  %t3 = lshr <3 x i32> %t1, %t272  ret <3 x i32> %t373}74 75define <3 x i32> @t5_vec_nonsplat_poison1(<3 x i32> %x, <3 x i32> %y) {76; CHECK-LABEL: @t5_vec_nonsplat_poison1(77; CHECK-NEXT:    [[T3:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 30, i32 poison, i32 30>78; CHECK-NEXT:    ret <3 x i32> [[T3]]79;80  %t0 = sub <3 x i32> <i32 32, i32 poison, i32 32>, %y81  %t1 = lshr <3 x i32> %x, %t082  %t2 = add <3 x i32> %y, <i32 -2, i32 poison, i32 -2>83  %t3 = lshr <3 x i32> %t1, %t284  ret <3 x i32> %t385}86 87; Some other shift opcodes88define i32 @t6_shl(i32 %x, i32 %y) {89; CHECK-LABEL: @t6_shl(90; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[X:%.*]], 3091; CHECK-NEXT:    ret i32 [[T3]]92;93  %t0 = sub i32 32, %y94  %t1 = shl nuw i32 %x, %t0 ; while there, test that we don't propagate partial 'nuw' flag95  %t2 = add i32 %y, -296  %t3 = shl nsw i32 %t1, %t2 ; while there, test that we don't propagate partial 'nsw' flag97  ret i32 %t398}99define i32 @t7_ashr(i32 %x, i32 %y) {100; CHECK-LABEL: @t7_ashr(101; CHECK-NEXT:    [[T3:%.*]] = ashr i32 [[X:%.*]], 30102; CHECK-NEXT:    ret i32 [[T3]]103;104  %t0 = sub i32 32, %y105  %t1 = ashr exact i32 %x, %t0 ; while there, test that we don't propagate partial 'exact' flag106  %t2 = add i32 %y, -2107  %t3 = ashr i32 %t1, %t2108  ret i32 %t3109}110 111; If the same flag is present on both shifts, it can be kept.112define i32 @t8_lshr_exact_flag_preservation(i32 %x, i32 %y) {113; CHECK-LABEL: @t8_lshr_exact_flag_preservation(114; CHECK-NEXT:    [[T3:%.*]] = lshr exact i32 [[X:%.*]], 30115; CHECK-NEXT:    ret i32 [[T3]]116;117  %t0 = sub i32 32, %y118  %t1 = lshr exact i32 %x, %t0119  %t2 = add i32 %y, -2120  %t3 = lshr exact i32 %t1, %t2121  ret i32 %t3122}123define i32 @t9_ashr_exact_flag_preservation(i32 %x, i32 %y) {124; CHECK-LABEL: @t9_ashr_exact_flag_preservation(125; CHECK-NEXT:    [[T3:%.*]] = ashr exact i32 [[X:%.*]], 30126; CHECK-NEXT:    ret i32 [[T3]]127;128  %t0 = sub i32 32, %y129  %t1 = ashr exact i32 %x, %t0130  %t2 = add i32 %y, -2131  %t3 = ashr exact i32 %t1, %t2132  ret i32 %t3133}134define i32 @t10_shl_nuw_flag_preservation(i32 %x, i32 %y) {135; CHECK-LABEL: @t10_shl_nuw_flag_preservation(136; CHECK-NEXT:    [[T3:%.*]] = shl nuw i32 [[X:%.*]], 30137; CHECK-NEXT:    ret i32 [[T3]]138;139  %t0 = sub i32 32, %y140  %t1 = shl nuw i32 %x, %t0141  %t2 = add i32 %y, -2142  %t3 = shl nuw nsw i32 %t1, %t2 ; only 'nuw' should be propagated.143  ret i32 %t3144}145define i32 @t11_shl_nsw_flag_preservation(i32 %x, i32 %y) {146; CHECK-LABEL: @t11_shl_nsw_flag_preservation(147; CHECK-NEXT:    [[T3:%.*]] = shl nsw i32 [[X:%.*]], 30148; CHECK-NEXT:    ret i32 [[T3]]149;150  %t0 = sub i32 32, %y151  %t1 = shl nsw i32 %x, %t0152  %t2 = add i32 %y, -2153  %t3 = shl nsw nuw i32 %t1, %t2 ; only 'nuw' should be propagated.154  ret i32 %t3155}156 157; Reduced from https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15587158@X = external global i32159define i64 @constantexpr(ptr %A) {160; CHECK-LABEL: @constantexpr(ptr %A) {161; CHECK-NEXT:    ret i64 0162;163  %L = load i64, ptr %A164  %V = add i64 ptrtoint (ptr @X to i64), 0165  %B2 = shl i64 %V, 0166  %B4 = ashr i64 %B2, %L167  %B = and i64 undef, %B4168  ret i64 %B169}170 171; No one-use tests since we will only produce a single instruction here.172 173; Negative tests174 175; Can't fold, total shift would be 32176define i32 @n12(i32 %x, i32 %y) {177; CHECK-LABEL: @n12(178; CHECK-NEXT:    [[T0:%.*]] = sub i32 30, [[Y:%.*]]179; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]180; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], 2181; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[T1]], [[T2]]182; CHECK-NEXT:    ret i32 [[T3]]183;184  %t0 = sub i32 30, %y185  %t1 = lshr i32 %x, %t0186  %t2 = add i32 %y, 2187  %t3 = lshr i32 %t1, %t2188  ret i32 %t3189}190; Can't fold, for second channel the shift would 32191define <2 x i32> @t13_vec(<2 x i32> %x, <2 x i32> %y) {192; CHECK-LABEL: @t13_vec(193; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i32> <i32 32, i32 30>, [[Y:%.*]]194; CHECK-NEXT:    [[T1:%.*]] = lshr <2 x i32> [[X:%.*]], [[T0]]195; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[Y]], <i32 -2, i32 2>196; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[T1]], [[T2]]197; CHECK-NEXT:    ret <2 x i32> [[T3]]198;199  %t0 = sub <2 x i32> <i32 32, i32 30>, %y200  %t1 = lshr <2 x i32> %x, %t0201  %t2 = add <2 x i32> %y, <i32 -2, i32 2>202  %t3 = lshr <2 x i32> %t1, %t2203  ret <2 x i32> %t3204}205 206; If we have different right-shifts, in general, we can't do anything with it.207define i32 @n13(i32 %x, i32 %y) {208; CHECK-LABEL: @n13(209; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]210; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]211; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -2212; CHECK-NEXT:    [[T3:%.*]] = ashr i32 [[T1]], [[T2]]213; CHECK-NEXT:    ret i32 [[T3]]214;215  %t0 = sub i32 32, %y216  %t1 = lshr i32 %x, %t0217  %t2 = add i32 %y, -2218  %t3 = ashr i32 %t1, %t2219  ret i32 %t3220}221define i32 @n14(i32 %x, i32 %y) {222; CHECK-LABEL: @n14(223; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]224; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]225; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -1226; CHECK-NEXT:    [[T3:%.*]] = ashr i32 [[T1]], [[T2]]227; CHECK-NEXT:    ret i32 [[T3]]228;229  %t0 = sub i32 32, %y230  %t1 = lshr i32 %x, %t0231  %t2 = add i32 %y, -1232  %t3 = ashr i32 %t1, %t2233  ret i32 %t3234}235define i32 @n15(i32 %x, i32 %y) {236; CHECK-LABEL: @n15(237; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]238; CHECK-NEXT:    [[T1:%.*]] = ashr i32 [[X:%.*]], [[T0]]239; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -2240; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[T1]], [[T2]]241; CHECK-NEXT:    ret i32 [[T3]]242;243  %t0 = sub i32 32, %y244  %t1 = ashr i32 %x, %t0245  %t2 = add i32 %y, -2246  %t3 = lshr i32 %t1, %t2247  ret i32 %t3248}249define i32 @n16(i32 %x, i32 %y) {250; CHECK-LABEL: @n16(251; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]252; CHECK-NEXT:    [[T1:%.*]] = ashr i32 [[X:%.*]], [[T0]]253; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -1254; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[T1]], [[T2]]255; CHECK-NEXT:    ret i32 [[T3]]256;257  %t0 = sub i32 32, %y258  %t1 = ashr i32 %x, %t0259  %t2 = add i32 %y, -1260  %t3 = lshr i32 %t1, %t2261  ret i32 %t3262}263 264; If the shift direction is different, then this should be handled elsewhere.265define i32 @n17(i32 %x, i32 %y) {266; CHECK-LABEL: @n17(267; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]268; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[X:%.*]], [[T0]]269; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -1270; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[T1]], [[T2]]271; CHECK-NEXT:    ret i32 [[T3]]272;273  %t0 = sub i32 32, %y274  %t1 = shl i32 %x, %t0275  %t2 = add i32 %y, -1276  %t3 = lshr i32 %t1, %t2277  ret i32 %t3278}279define i32 @n18(i32 %x, i32 %y) {280; CHECK-LABEL: @n18(281; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]282; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[X:%.*]], [[T0]]283; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -1284; CHECK-NEXT:    [[T3:%.*]] = ashr i32 [[T1]], [[T2]]285; CHECK-NEXT:    ret i32 [[T3]]286;287  %t0 = sub i32 32, %y288  %t1 = shl i32 %x, %t0289  %t2 = add i32 %y, -1290  %t3 = ashr i32 %t1, %t2291  ret i32 %t3292}293define i32 @n19(i32 %x, i32 %y) {294; CHECK-LABEL: @n19(295; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]296; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]297; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -1298; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[T1]], [[T2]]299; CHECK-NEXT:    ret i32 [[T3]]300;301  %t0 = sub i32 32, %y302  %t1 = lshr i32 %x, %t0303  %t2 = add i32 %y, -1304  %t3 = shl i32 %t1, %t2305  ret i32 %t3306}307define i32 @n20(i32 %x, i32 %y) {308; CHECK-LABEL: @n20(309; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[Y:%.*]]310; CHECK-NEXT:    [[T1:%.*]] = ashr i32 [[X:%.*]], [[T0]]311; CHECK-NEXT:    [[T2:%.*]] = add i32 [[Y]], -1312; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[T1]], [[T2]]313; CHECK-NEXT:    ret i32 [[T3]]314;315  %t0 = sub i32 32, %y316  %t1 = ashr i32 %x, %t0317  %t2 = add i32 %y, -1318  %t3 = shl i32 %t1, %t2319  ret i32 %t3320}321 322; See https://bugs.llvm.org/show_bug.cgi?id=44802323define i3 @pr44802(i3 %t0) {324; CHECK-LABEL: @pr44802(325; CHECK-NEXT:    [[T1:%.*]] = sub i3 0, [[T0:%.*]]326; CHECK-NEXT:    [[T2:%.*]] = icmp ne i3 [[T0]], 0327; CHECK-NEXT:    [[T3:%.*]] = zext i1 [[T2]] to i3328; CHECK-NEXT:    [[T4:%.*]] = lshr i3 [[T1]], [[T3]]329; CHECK-NEXT:    [[T5:%.*]] = lshr i3 [[T4]], [[T3]]330; CHECK-NEXT:    ret i3 [[T5]]331;332  %t1 = sub i3 0, %t0333  %t2 = icmp ne i3 %t0, 0334  %t3 = zext i1 %t2 to i3335  %t4 = lshr i3 %t1, %t3336  %t5 = lshr i3 %t4, %t3337  ret i3 %t5338}339