1cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2cee313d2SEric Christopher; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s 3cee313d2SEric Christophertarget 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" 4cee313d2SEric Christopher 5cee313d2SEric Christopher; Aggressive Instcombine should be able to reduce width of these constant 6cee313d2SEric Christopher; expressions, without crashing. 7cee313d2SEric Christopher 8cee313d2SEric Christopherdeclare i32 @use32(i32) 9cee313d2SEric Christopherdeclare <2 x i32> @use32_vec(<2 x i32>) 10*137674f8SJun Madeclare <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32>) 11cee313d2SEric Christopher 12cee313d2SEric Christopher;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 13cee313d2SEric Christopher;; These tests check cases where expression dag post-dominated by TruncInst 14cee313d2SEric Christopher;; contains instruction, which has more than one usage. 15cee313d2SEric Christopher;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 16cee313d2SEric Christopher 17cee313d2SEric Christopherdefine void @const_expression_mul() { 18cee313d2SEric Christopher; CHECK-LABEL: @const_expression_mul( 19cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 242) 20cee313d2SEric Christopher; CHECK-NEXT: ret void 21cee313d2SEric Christopher; 22cee313d2SEric Christopher %A = mul i64 11, 22 23cee313d2SEric Christopher %T = trunc i64 %A to i32 24cee313d2SEric Christopher call i32 @use32(i32 %T) 25cee313d2SEric Christopher ret void 26cee313d2SEric Christopher} 27cee313d2SEric Christopher 28cee313d2SEric Christopherdefine void @const_expression_zext() { 29cee313d2SEric Christopher; CHECK-LABEL: @const_expression_zext( 30cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 33) 31cee313d2SEric Christopher; CHECK-NEXT: ret void 32cee313d2SEric Christopher; 33cee313d2SEric Christopher %A = zext i32 33 to i64 34cee313d2SEric Christopher %T = trunc i64 %A to i32 35cee313d2SEric Christopher call i32 @use32(i32 %T) 36cee313d2SEric Christopher ret void 37cee313d2SEric Christopher} 38cee313d2SEric Christopher 39cee313d2SEric Christopherdefine void @const_expression_trunc() { 40cee313d2SEric Christopher; CHECK-LABEL: @const_expression_trunc( 41cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 44) 42cee313d2SEric Christopher; CHECK-NEXT: ret void 43cee313d2SEric Christopher; 44cee313d2SEric Christopher %T = trunc i64 44 to i32 45cee313d2SEric Christopher call i32 @use32(i32 %T) 46cee313d2SEric Christopher ret void 47cee313d2SEric Christopher} 48cee313d2SEric Christopher 49cee313d2SEric Christopher; Check that we handle constant expression trunc instruction, when it is a leaf 50cee313d2SEric Christopher; of other trunc expression pattern: 51cee313d2SEric Christopher; 1. %T1 is the constant expression trunc instruction. 52cee313d2SEric Christopher; 2. %T2->%T1 is the trunc expression pattern we want to reduce. 53cee313d2SEric Christopherdefine void @const_expression_trunc_leaf() { 54cee313d2SEric Christopher; CHECK-LABEL: @const_expression_trunc_leaf( 55cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 44) 56cee313d2SEric Christopher; CHECK-NEXT: ret void 57cee313d2SEric Christopher; 58cee313d2SEric Christopher %T1 = trunc i64 44 to i48 59cee313d2SEric Christopher %T2 = trunc i48 %T1 to i32 60cee313d2SEric Christopher call i32 @use32(i32 %T2) 61cee313d2SEric Christopher ret void 62cee313d2SEric Christopher} 63cee313d2SEric Christopher 64cee313d2SEric Christopher; Check that we handle zext instruction, which turns into trunc instruction. 65cee313d2SEric Christopher; Notice that there are two expression patterns below: 66cee313d2SEric Christopher; 1. %T2->%T1 67cee313d2SEric Christopher; 2. %T1`->%A (where %T1` is the reduced node of %T1 into trunc instruction) 68cee313d2SEric Christopherdefine void @const_expression_zext_to_trunc() { 69cee313d2SEric Christopher; CHECK-LABEL: @const_expression_zext_to_trunc( 70cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use32(i32 44) 71cee313d2SEric Christopher; CHECK-NEXT: ret void 72cee313d2SEric Christopher; 73cee313d2SEric Christopher %A = add i64 11, 33 74cee313d2SEric Christopher %T1 = zext i64 %A to i128 75cee313d2SEric Christopher %T2 = trunc i128 %T1 to i32 76cee313d2SEric Christopher call i32 @use32(i32 %T2) 77cee313d2SEric Christopher ret void 78cee313d2SEric Christopher} 79cee313d2SEric Christopher 80cee313d2SEric Christopherdefine void @const_expression_mul_vec() { 81cee313d2SEric Christopher; CHECK-LABEL: @const_expression_mul_vec( 82cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @use32_vec(<2 x i32> <i32 24531, i32 24864>) 83cee313d2SEric Christopher; CHECK-NEXT: ret void 84cee313d2SEric Christopher; 85cee313d2SEric Christopher %A = mul <2 x i64> <i64 111, i64 112>, <i64 221, i64 222> 86cee313d2SEric Christopher %T = trunc <2 x i64> %A to <2 x i32> 87cee313d2SEric Christopher call <2 x i32> @use32_vec(<2 x i32> %T) 88cee313d2SEric Christopher ret void 89cee313d2SEric Christopher} 90cee313d2SEric Christopher 91cee313d2SEric Christopherdefine void @const_expression_zext_vec() { 92cee313d2SEric Christopher; CHECK-LABEL: @const_expression_zext_vec( 93cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @use32_vec(<2 x i32> <i32 331, i32 332>) 94cee313d2SEric Christopher; CHECK-NEXT: ret void 95cee313d2SEric Christopher; 96cee313d2SEric Christopher %A = zext <2 x i32> <i32 331, i32 332> to <2 x i64> 97cee313d2SEric Christopher %T = trunc <2 x i64> %A to <2 x i32> 98cee313d2SEric Christopher call <2 x i32> @use32_vec(<2 x i32> %T) 99cee313d2SEric Christopher ret void 100cee313d2SEric Christopher} 101cee313d2SEric Christopher 102cee313d2SEric Christopherdefine void @const_expression_trunc_vec() { 103cee313d2SEric Christopher; CHECK-LABEL: @const_expression_trunc_vec( 104cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @use32_vec(<2 x i32> <i32 551, i32 552>) 105cee313d2SEric Christopher; CHECK-NEXT: ret void 106cee313d2SEric Christopher; 107cee313d2SEric Christopher %T = trunc <2 x i64> <i64 551, i64 552> to <2 x i32> 108cee313d2SEric Christopher call <2 x i32> @use32_vec(<2 x i32> %T) 109cee313d2SEric Christopher ret void 110cee313d2SEric Christopher} 111*137674f8SJun Ma 112*137674f8SJun Madefine void @const_expression_mul_scale_vec() { 113*137674f8SJun Ma; CHECK-LABEL: @const_expression_mul_scale_vec( 114*137674f8SJun Ma; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> zeroinitializer) 115*137674f8SJun Ma; CHECK-NEXT: ret void 116*137674f8SJun Ma; 117*137674f8SJun Ma %A = mul <vscale x 2 x i64> zeroinitializer, zeroinitializer 118*137674f8SJun Ma %T = trunc <vscale x 2 x i64> %A to <vscale x 2 x i32> 119*137674f8SJun Ma call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> %T) 120*137674f8SJun Ma ret void 121*137674f8SJun Ma} 122*137674f8SJun Ma 123*137674f8SJun Madefine void @const_expression_zext_scale_vec() { 124*137674f8SJun Ma; CHECK-LABEL: @const_expression_zext_scale_vec( 125*137674f8SJun Ma; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> zeroinitializer) 126*137674f8SJun Ma; CHECK-NEXT: ret void 127*137674f8SJun Ma; 128*137674f8SJun Ma %A = zext <vscale x 2 x i32> zeroinitializer to <vscale x 2 x i64> 129*137674f8SJun Ma %T = trunc <vscale x 2 x i64> %A to <vscale x 2 x i32> 130*137674f8SJun Ma call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> %T) 131*137674f8SJun Ma ret void 132*137674f8SJun Ma} 133*137674f8SJun Ma 134*137674f8SJun Madefine void @const_expression_trunc_scale_vec() { 135*137674f8SJun Ma; CHECK-LABEL: @const_expression_trunc_scale_vec( 136*137674f8SJun Ma; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> zeroinitializer) 137*137674f8SJun Ma; CHECK-NEXT: ret void 138*137674f8SJun Ma; 139*137674f8SJun Ma %T = trunc <vscale x 2 x i64> zeroinitializer to <vscale x 2 x i32> 140*137674f8SJun Ma call <vscale x 2 x i32> @use32_scale_vec(<vscale x 2 x i32> %T) 141*137674f8SJun Ma ret void 142*137674f8SJun Ma} 143