143 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"4 5; Aggressive Instcombine should be able to reduce width of these constant6; expressions, without crashing.7 8declare i32 @use32(i32)9declare <2 x i32> @use32_vec(<2 x i32>)10declare <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32>)11 12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13;; These tests check cases where expression dag post-dominated by TruncInst14;; contains instruction, which has more than one usage.15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16 17define void @const_expression_mul() {18; CHECK-LABEL: @const_expression_mul(19; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 242)20; CHECK-NEXT: ret void21;22 %A = mul i64 11, 2223 %T = trunc i64 %A to i3224 call i32 @use32(i32 %T)25 ret void26}27 28define void @const_expression_zext() {29; CHECK-LABEL: @const_expression_zext(30; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 33)31; CHECK-NEXT: ret void32;33 %A = zext i32 33 to i6434 %T = trunc i64 %A to i3235 call i32 @use32(i32 %T)36 ret void37}38 39define void @const_expression_trunc() {40; CHECK-LABEL: @const_expression_trunc(41; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 44)42; CHECK-NEXT: ret void43;44 %T = trunc i64 44 to i3245 call i32 @use32(i32 %T)46 ret void47}48 49; Check that we handle constant expression trunc instruction, when it is a leaf50; of other trunc expression pattern:51; 1. %T1 is the constant expression trunc instruction.52; 2. %T2->%T1 is the trunc expression pattern we want to reduce.53define void @const_expression_trunc_leaf() {54; CHECK-LABEL: @const_expression_trunc_leaf(55; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 44)56; CHECK-NEXT: ret void57;58 %T1 = trunc i64 44 to i4859 %T2 = trunc i48 %T1 to i3260 call i32 @use32(i32 %T2)61 ret void62}63 64; Check that we handle zext instruction, which turns into trunc instruction.65; Notice that there are two expression patterns below:66; 1. %T2->%T167; 2. %T1`->%A (where %T1` is the reduced node of %T1 into trunc instruction)68define void @const_expression_zext_to_trunc() {69; CHECK-LABEL: @const_expression_zext_to_trunc(70; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 44)71; CHECK-NEXT: ret void72;73 %A = add i64 11, 3374 %T1 = zext i64 %A to i12875 %T2 = trunc i128 %T1 to i3276 call i32 @use32(i32 %T2)77 ret void78}79 80define void @const_expression_mul_vec() {81; CHECK-LABEL: @const_expression_mul_vec(82; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @use32_vec(<2 x i32> <i32 24531, i32 24864>)83; CHECK-NEXT: ret void84;85 %A = mul <2 x i64> <i64 111, i64 112>, <i64 221, i64 222>86 %T = trunc <2 x i64> %A to <2 x i32>87 call <2 x i32> @use32_vec(<2 x i32> %T)88 ret void89}90 91define void @const_expression_zext_vec() {92; CHECK-LABEL: @const_expression_zext_vec(93; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @use32_vec(<2 x i32> <i32 331, i32 332>)94; CHECK-NEXT: ret void95;96 %A = zext <2 x i32> <i32 331, i32 332> to <2 x i64>97 %T = trunc <2 x i64> %A to <2 x i32>98 call <2 x i32> @use32_vec(<2 x i32> %T)99 ret void100}101 102define void @const_expression_trunc_vec() {103; CHECK-LABEL: @const_expression_trunc_vec(104; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @use32_vec(<2 x i32> <i32 551, i32 552>)105; CHECK-NEXT: ret void106;107 %T = trunc <2 x i64> <i64 551, i64 552> to <2 x i32>108 call <2 x i32> @use32_vec(<2 x i32> %T)109 ret void110}111 112define void @const_expression_mul_scale_vec() {113; CHECK-LABEL: @const_expression_mul_scale_vec(114; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> zeroinitializer)115; CHECK-NEXT: ret void116;117 %A = mul <vscale x 2 x i64> zeroinitializer, zeroinitializer118 %T = trunc <vscale x 2 x i64> %A to <vscale x 2 x i32>119 call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> %T)120 ret void121}122 123define void @const_expression_zext_scale_vec() {124; CHECK-LABEL: @const_expression_zext_scale_vec(125; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> zeroinitializer)126; CHECK-NEXT: ret void127;128 %A = zext <vscale x 2 x i32> zeroinitializer to <vscale x 2 x i64>129 %T = trunc <vscale x 2 x i64> %A to <vscale x 2 x i32>130 call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> %T)131 ret void132}133 134define void @const_expression_trunc_scale_vec() {135; CHECK-LABEL: @const_expression_trunc_scale_vec(136; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> zeroinitializer)137; CHECK-NEXT: ret void138;139 %T = trunc <vscale x 2 x i64> zeroinitializer to <vscale x 2 x i32>140 call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> %T)141 ret void142}143