1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Workertarget 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" 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; Instcombine should be able to eliminate all of these ext casts. 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdeclare void @use(i32) 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine i64 @test1(i64 %a) { 9*9880d681SAndroid Build Coastguard Worker %b = trunc i64 %a to i32 10*9880d681SAndroid Build Coastguard Worker %c = and i32 %b, 15 11*9880d681SAndroid Build Coastguard Worker %d = zext i32 %c to i64 12*9880d681SAndroid Build Coastguard Worker call void @use(i32 %b) 13*9880d681SAndroid Build Coastguard Worker ret i64 %d 14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 15*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ext 16*9880d681SAndroid Build Coastguard Worker; CHECK: ret 17*9880d681SAndroid Build Coastguard Worker} 18*9880d681SAndroid Build Coastguard Workerdefine i64 @test2(i64 %a) { 19*9880d681SAndroid Build Coastguard Worker %b = trunc i64 %a to i32 20*9880d681SAndroid Build Coastguard Worker %c = shl i32 %b, 4 21*9880d681SAndroid Build Coastguard Worker %q = ashr i32 %c, 4 22*9880d681SAndroid Build Coastguard Worker %d = sext i32 %q to i64 23*9880d681SAndroid Build Coastguard Worker call void @use(i32 %b) 24*9880d681SAndroid Build Coastguard Worker ret i64 %d 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 26*9880d681SAndroid Build Coastguard Worker; CHECK: shl i64 %a, 36 27*9880d681SAndroid Build Coastguard Worker; CHECK: %d = ashr exact i64 {{.*}}, 36 28*9880d681SAndroid Build Coastguard Worker; CHECK: ret i64 %d 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Workerdefine i64 @test3(i64 %a) { 31*9880d681SAndroid Build Coastguard Worker %b = trunc i64 %a to i32 32*9880d681SAndroid Build Coastguard Worker %c = and i32 %b, 8 33*9880d681SAndroid Build Coastguard Worker %d = zext i32 %c to i64 34*9880d681SAndroid Build Coastguard Worker call void @use(i32 %b) 35*9880d681SAndroid Build Coastguard Worker ret i64 %d 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3( 37*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ext 38*9880d681SAndroid Build Coastguard Worker; CHECK: ret 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Workerdefine i64 @test4(i64 %a) { 41*9880d681SAndroid Build Coastguard Worker %b = trunc i64 %a to i32 42*9880d681SAndroid Build Coastguard Worker %c = and i32 %b, 8 43*9880d681SAndroid Build Coastguard Worker %x = xor i32 %c, 8 44*9880d681SAndroid Build Coastguard Worker %d = zext i32 %x to i64 45*9880d681SAndroid Build Coastguard Worker call void @use(i32 %b) 46*9880d681SAndroid Build Coastguard Worker ret i64 %d 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4( 48*9880d681SAndroid Build Coastguard Worker; CHECK: = and i64 %a, 8 49*9880d681SAndroid Build Coastguard Worker; CHECK: = xor i64 {{.*}}, 8 50*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ext 51*9880d681SAndroid Build Coastguard Worker; CHECK: ret 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i32 %A) { 55*9880d681SAndroid Build Coastguard Worker %B = zext i32 %A to i128 56*9880d681SAndroid Build Coastguard Worker %C = lshr i128 %B, 16 57*9880d681SAndroid Build Coastguard Worker %D = trunc i128 %C to i32 58*9880d681SAndroid Build Coastguard Worker ret i32 %D 59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 60*9880d681SAndroid Build Coastguard Worker; CHECK: %C = lshr i32 %A, 16 61*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %C 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i64 %A) { 65*9880d681SAndroid Build Coastguard Worker %B = zext i64 %A to i128 66*9880d681SAndroid Build Coastguard Worker %C = lshr i128 %B, 32 67*9880d681SAndroid Build Coastguard Worker %D = trunc i128 %C to i32 68*9880d681SAndroid Build Coastguard Worker ret i32 %D 69*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6( 70*9880d681SAndroid Build Coastguard Worker; CHECK: %C = lshr i64 %A, 32 71*9880d681SAndroid Build Coastguard Worker; CHECK: %D = trunc i64 %C to i32 72*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %D 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerdefine i92 @test7(i64 %A) { 76*9880d681SAndroid Build Coastguard Worker %B = zext i64 %A to i128 77*9880d681SAndroid Build Coastguard Worker %C = lshr i128 %B, 32 78*9880d681SAndroid Build Coastguard Worker %D = trunc i128 %C to i92 79*9880d681SAndroid Build Coastguard Worker ret i92 %D 80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7( 81*9880d681SAndroid Build Coastguard Worker; CHECK: %B = zext i64 %A to i92 82*9880d681SAndroid Build Coastguard Worker; CHECK: %C = lshr i92 %B, 32 83*9880d681SAndroid Build Coastguard Worker; CHECK: ret i92 %C 84*9880d681SAndroid Build Coastguard Worker} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerdefine i64 @test8(i32 %A, i32 %B) { 87*9880d681SAndroid Build Coastguard Worker %tmp38 = zext i32 %A to i128 88*9880d681SAndroid Build Coastguard Worker %tmp32 = zext i32 %B to i128 89*9880d681SAndroid Build Coastguard Worker %tmp33 = shl i128 %tmp32, 32 90*9880d681SAndroid Build Coastguard Worker %ins35 = or i128 %tmp33, %tmp38 91*9880d681SAndroid Build Coastguard Worker %tmp42 = trunc i128 %ins35 to i64 92*9880d681SAndroid Build Coastguard Worker ret i64 %tmp42 93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8( 94*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp38 = zext i32 %A to i64 95*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp32 = zext i32 %B to i64 96*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp33 = shl nuw i64 %tmp32, 32 97*9880d681SAndroid Build Coastguard Worker; CHECK: %ins35 = or i64 %tmp33, %tmp38 98*9880d681SAndroid Build Coastguard Worker; CHECK: ret i64 %ins35 99*9880d681SAndroid Build Coastguard Worker} 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerdefine i8 @test9(i32 %X) { 102*9880d681SAndroid Build Coastguard Worker %Y = and i32 %X, 42 103*9880d681SAndroid Build Coastguard Worker %Z = trunc i32 %Y to i8 104*9880d681SAndroid Build Coastguard Worker ret i8 %Z 105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9( 106*9880d681SAndroid Build Coastguard Worker; CHECK: trunc 107*9880d681SAndroid Build Coastguard Worker; CHECK: and 108*9880d681SAndroid Build Coastguard Worker; CHECK: ret 109*9880d681SAndroid Build Coastguard Worker} 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker; rdar://8808586 112*9880d681SAndroid Build Coastguard Workerdefine i8 @test10(i32 %X) { 113*9880d681SAndroid Build Coastguard Worker %Y = trunc i32 %X to i8 114*9880d681SAndroid Build Coastguard Worker %Z = and i8 %Y, 42 115*9880d681SAndroid Build Coastguard Worker ret i8 %Z 116*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10( 117*9880d681SAndroid Build Coastguard Worker; CHECK: trunc 118*9880d681SAndroid Build Coastguard Worker; CHECK: and 119*9880d681SAndroid Build Coastguard Worker; CHECK: ret 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker; PR25543 123*9880d681SAndroid Build Coastguard Worker; https://llvm.org/bugs/show_bug.cgi?id=25543 124*9880d681SAndroid Build Coastguard Worker; This is an extractelement. 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerdefine i32 @trunc_bitcast1(<4 x i32> %v) { 127*9880d681SAndroid Build Coastguard Worker %bc = bitcast <4 x i32> %v to i128 128*9880d681SAndroid Build Coastguard Worker %shr = lshr i128 %bc, 32 129*9880d681SAndroid Build Coastguard Worker %ext = trunc i128 %shr to i32 130*9880d681SAndroid Build Coastguard Worker ret i32 %ext 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @trunc_bitcast1( 133*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %ext = extractelement <4 x i32> %v, i32 1 134*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %ext 135*9880d681SAndroid Build Coastguard Worker} 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker; A bitcast may still be required. 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Workerdefine i32 @trunc_bitcast2(<2 x i64> %v) { 140*9880d681SAndroid Build Coastguard Worker %bc = bitcast <2 x i64> %v to i128 141*9880d681SAndroid Build Coastguard Worker %shr = lshr i128 %bc, 64 142*9880d681SAndroid Build Coastguard Worker %ext = trunc i128 %shr to i32 143*9880d681SAndroid Build Coastguard Worker ret i32 %ext 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @trunc_bitcast2( 146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %bc1 = bitcast <2 x i64> %v to <4 x i32> 147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %ext = extractelement <4 x i32> %bc1, i32 2 148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %ext 149*9880d681SAndroid Build Coastguard Worker} 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker; The right shift is optional. 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerdefine i32 @trunc_bitcast3(<4 x i32> %v) { 154*9880d681SAndroid Build Coastguard Worker %bc = bitcast <4 x i32> %v to i128 155*9880d681SAndroid Build Coastguard Worker %ext = trunc i128 %bc to i32 156*9880d681SAndroid Build Coastguard Worker ret i32 %ext 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @trunc_bitcast3( 159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %ext = extractelement <4 x i32> %v, i32 0 160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i32 %ext 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @trunc_shl_infloop( 164*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp = lshr i64 %arg, 1 165*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp21 = shl i64 %tmp, 2 166*9880d681SAndroid Build Coastguard Worker; CHECK: %tmp2 = trunc i64 %tmp21 to i32 167*9880d681SAndroid Build Coastguard Worker; CHECK: icmp sgt i32 %tmp2, 0 168*9880d681SAndroid Build Coastguard Workerdefine void @trunc_shl_infloop(i64 %arg) { 169*9880d681SAndroid Build Coastguard Workerbb: 170*9880d681SAndroid Build Coastguard Worker %tmp = lshr i64 %arg, 1 171*9880d681SAndroid Build Coastguard Worker %tmp1 = trunc i64 %tmp to i32 172*9880d681SAndroid Build Coastguard Worker %tmp2 = shl i32 %tmp1, 2 173*9880d681SAndroid Build Coastguard Worker %tmp3 = icmp sgt i32 %tmp2, 0 174*9880d681SAndroid Build Coastguard Worker br i1 %tmp3, label %bb2, label %bb1 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Workerbb1: 177*9880d681SAndroid Build Coastguard Worker %tmp5 = sub i32 0, %tmp1 178*9880d681SAndroid Build Coastguard Worker %tmp6 = sub i32 %tmp5, 1 179*9880d681SAndroid Build Coastguard Worker unreachable 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Workerbb2: 182*9880d681SAndroid Build Coastguard Worker unreachable 183*9880d681SAndroid Build Coastguard Worker} 184