1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(i32) 5declare void @usevec(<2 x i32>) 6 7define <2 x double> @fpext_fpext(<2 x half> %x, half %y, i32 %index) { 8; CHECK-LABEL: @fpext_fpext( 9; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x half> [[X:%.*]], half [[Y:%.*]], i32 [[INDEX:%.*]] 10; CHECK-NEXT: [[I:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> 11; CHECK-NEXT: ret <2 x double> [[I]] 12; 13 %v = fpext <2 x half> %x to <2 x double> 14 %s = fpext half %y to double 15 %i = insertelement <2 x double> %v, double %s, i32 %index 16 ret <2 x double> %i 17} 18 19define <2 x i32> @sext_sext(<2 x i8> %x, i8 %y, i32 %index) { 20; CHECK-LABEL: @sext_sext( 21; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 [[Y:%.*]], i32 [[INDEX:%.*]] 22; CHECK-NEXT: [[I:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i32> 23; CHECK-NEXT: ret <2 x i32> [[I]] 24; 25 %v = sext <2 x i8> %x to <2 x i32> 26 %s = sext i8 %y to i32 27 %i = insertelement <2 x i32> %v, i32 %s, i32 %index 28 ret <2 x i32> %i 29} 30 31define <2 x i12> @zext_zext(<2 x i8> %x, i8 %y, i32 %index) { 32; CHECK-LABEL: @zext_zext( 33; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 [[Y:%.*]], i32 [[INDEX:%.*]] 34; CHECK-NEXT: [[I:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i12> 35; CHECK-NEXT: ret <2 x i12> [[I]] 36; 37 %v = zext <2 x i8> %x to <2 x i12> 38 %s = zext i8 %y to i12 39 %i = insertelement <2 x i12> %v, i12 %s, i32 %index 40 ret <2 x i12> %i 41} 42 43; negative test - need same source type 44 45define <2 x double> @fpext_fpext_types(<2 x half> %x, float %y, i32 %index) { 46; CHECK-LABEL: @fpext_fpext_types( 47; CHECK-NEXT: [[V:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x double> 48; CHECK-NEXT: [[S:%.*]] = fpext float [[Y:%.*]] to double 49; CHECK-NEXT: [[I:%.*]] = insertelement <2 x double> [[V]], double [[S]], i32 [[INDEX:%.*]] 50; CHECK-NEXT: ret <2 x double> [[I]] 51; 52 %v = fpext <2 x half> %x to <2 x double> 53 %s = fpext float %y to double 54 %i = insertelement <2 x double> %v, double %s, i32 %index 55 ret <2 x double> %i 56} 57 58; negative test - need same source type 59 60define <2 x i32> @sext_sext_types(<2 x i16> %x, i8 %y, i32 %index) { 61; CHECK-LABEL: @sext_sext_types( 62; CHECK-NEXT: [[V:%.*]] = sext <2 x i16> [[X:%.*]] to <2 x i32> 63; CHECK-NEXT: [[S:%.*]] = sext i8 [[Y:%.*]] to i32 64; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i32> [[V]], i32 [[S]], i32 [[INDEX:%.*]] 65; CHECK-NEXT: ret <2 x i32> [[I]] 66; 67 %v = sext <2 x i16> %x to <2 x i32> 68 %s = sext i8 %y to i32 69 %i = insertelement <2 x i32> %v, i32 %s, i32 %index 70 ret <2 x i32> %i 71} 72 73; negative test - need same extend opcode 74 75define <2 x i12> @sext_zext(<2 x i8> %x, i8 %y, i32 %index) { 76; CHECK-LABEL: @sext_zext( 77; CHECK-NEXT: [[V:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i12> 78; CHECK-NEXT: [[S:%.*]] = zext i8 [[Y:%.*]] to i12 79; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i12> [[V]], i12 [[S]], i32 [[INDEX:%.*]] 80; CHECK-NEXT: ret <2 x i12> [[I]] 81; 82 %v = sext <2 x i8> %x to <2 x i12> 83 %s = zext i8 %y to i12 84 %i = insertelement <2 x i12> %v, i12 %s, i32 %index 85 ret <2 x i12> %i 86} 87 88; negative test - don't trade scalar extend for vector extend 89 90define <2 x i32> @sext_sext_use1(<2 x i8> %x, i8 %y, i32 %index) { 91; CHECK-LABEL: @sext_sext_use1( 92; CHECK-NEXT: [[V:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32> 93; CHECK-NEXT: call void @usevec(<2 x i32> [[V]]) 94; CHECK-NEXT: [[S:%.*]] = sext i8 [[Y:%.*]] to i32 95; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i32> [[V]], i32 [[S]], i32 [[INDEX:%.*]] 96; CHECK-NEXT: ret <2 x i32> [[I]] 97; 98 %v = sext <2 x i8> %x to <2 x i32> 99 call void @usevec(<2 x i32> %v) 100 %s = sext i8 %y to i32 101 %i = insertelement <2 x i32> %v, i32 %s, i32 %index 102 ret <2 x i32> %i 103} 104 105define <2 x i32> @zext_zext_use2(<2 x i8> %x, i8 %y, i32 %index) { 106; CHECK-LABEL: @zext_zext_use2( 107; CHECK-NEXT: [[S:%.*]] = zext i8 [[Y:%.*]] to i32 108; CHECK-NEXT: call void @use(i32 [[S]]) 109; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 [[Y]], i32 [[INDEX:%.*]] 110; CHECK-NEXT: [[I:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32> 111; CHECK-NEXT: ret <2 x i32> [[I]] 112; 113 %v = zext <2 x i8> %x to <2 x i32> 114 %s = zext i8 %y to i32 115 call void @use(i32 %s) 116 %i = insertelement <2 x i32> %v, i32 %s, i32 %index 117 ret <2 x i32> %i 118} 119 120; negative test - don't create an extra extend 121 122define <2 x i32> @zext_zext_use3(<2 x i8> %x, i8 %y, i32 %index) { 123; CHECK-LABEL: @zext_zext_use3( 124; CHECK-NEXT: [[V:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32> 125; CHECK-NEXT: call void @usevec(<2 x i32> [[V]]) 126; CHECK-NEXT: [[S:%.*]] = zext i8 [[Y:%.*]] to i32 127; CHECK-NEXT: call void @use(i32 [[S]]) 128; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i32> [[V]], i32 [[S]], i32 [[INDEX:%.*]] 129; CHECK-NEXT: ret <2 x i32> [[I]] 130; 131 %v = zext <2 x i8> %x to <2 x i32> 132 call void @usevec(<2 x i32> %v) 133 %s = zext i8 %y to i32 134 call void @use(i32 %s) 135 %i = insertelement <2 x i32> %v, i32 %s, i32 %index 136 ret <2 x i32> %i 137} 138