1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 target datalayout = "n8:16:32:64" 5 6 define i32 @test1(i32 %x) { 7 ; CHECK-LABEL: @test1( 8 ; CHECK-NEXT: [[SEXT:%.*]] = shl i32 %x, 16 9 ; CHECK-NEXT: [[TMP_3:%.*]] = ashr exact i32 [[SEXT]], 16 10 ; CHECK-NEXT: ret i32 [[TMP_3]] 11 ; 12 %tmp.1 = and i32 %x, 65535 13 %tmp.2 = xor i32 %tmp.1, -32768 14 %tmp.3 = add i32 %tmp.2, 32768 15 ret i32 %tmp.3 16 } 17 18 define i32 @test2(i32 %x) { 19 ; CHECK-LABEL: @test2( 20 ; CHECK-NEXT: [[SEXT:%.*]] = shl i32 %x, 16 21 ; CHECK-NEXT: [[TMP_3:%.*]] = ashr exact i32 [[SEXT]], 16 22 ; CHECK-NEXT: ret i32 [[TMP_3]] 23 ; 24 %tmp.1 = and i32 %x, 65535 25 %tmp.2 = xor i32 %tmp.1, 32768 26 %tmp.3 = add i32 %tmp.2, -32768 27 ret i32 %tmp.3 28 } 29 30 define i32 @test3(i16 %P) { 31 ; CHECK-LABEL: @test3( 32 ; CHECK-NEXT: [[TMP_5:%.*]] = sext i16 %P to i32 33 ; CHECK-NEXT: ret i32 [[TMP_5]] 34 ; 35 %tmp.1 = zext i16 %P to i32 36 %tmp.4 = xor i32 %tmp.1, 32768 37 %tmp.5 = add i32 %tmp.4, -32768 38 ret i32 %tmp.5 39 } 40 41 define i32 @test4(i32 %x) { 42 ; CHECK-LABEL: @test4( 43 ; CHECK-NEXT: [[SEXT:%.*]] = shl i32 %x, 24 44 ; CHECK-NEXT: [[TMP_3:%.*]] = ashr exact i32 [[SEXT]], 24 45 ; CHECK-NEXT: ret i32 [[TMP_3]] 46 ; 47 %tmp.1 = and i32 %x, 255 48 %tmp.2 = xor i32 %tmp.1, 128 49 %tmp.3 = add i32 %tmp.2, -128 50 ret i32 %tmp.3 51 } 52 53 define i32 @test5(i32 %x) { 54 ; CHECK-LABEL: @test5( 55 ; CHECK-NEXT: [[TMP_2:%.*]] = shl i32 %x, 16 56 ; CHECK-NEXT: [[TMP_4:%.*]] = ashr exact i32 [[TMP_2]], 16 57 ; CHECK-NEXT: ret i32 [[TMP_4]] 58 ; 59 %tmp.2 = shl i32 %x, 16 60 %tmp.4 = ashr i32 %tmp.2, 16 61 ret i32 %tmp.4 62 } 63 64 ; If the shift amount equals the difference in width of the destination 65 ; and source scalar types: 66 ; ashr (shl (zext X), C), C --> sext X 67 68 define i32 @test6(i16 %P) { 69 ; CHECK-LABEL: @test6( 70 ; CHECK-NEXT: [[TMP_5:%.*]] = sext i16 %P to i32 71 ; CHECK-NEXT: ret i32 [[TMP_5]] 72 ; 73 %tmp.1 = zext i16 %P to i32 74 %sext1 = shl i32 %tmp.1, 16 75 %tmp.5 = ashr i32 %sext1, 16 76 ret i32 %tmp.5 77 } 78 79 ; Vectors should get the same fold as above. 80 81 define <2 x i32> @test6_splat_vec(<2 x i12> %P) { 82 ; CHECK-LABEL: @test6_splat_vec( 83 ; CHECK-NEXT: [[ASHR:%.*]] = sext <2 x i12> %P to <2 x i32> 84 ; CHECK-NEXT: ret <2 x i32> [[ASHR]] 85 ; 86 %z = zext <2 x i12> %P to <2 x i32> 87 %shl = shl <2 x i32> %z, <i32 20, i32 20> 88 %ashr = ashr <2 x i32> %shl, <i32 20, i32 20> 89 ret <2 x i32> %ashr 90 } 91 92 define i32 @test7(i32 %x) { 93 ; CHECK-LABEL: @test7( 94 ; CHECK-NEXT: [[SUB:%.*]] = ashr i32 %x, 5 95 ; CHECK-NEXT: ret i32 [[SUB]] 96 ; 97 %shr = lshr i32 %x, 5 98 %xor = xor i32 %shr, 67108864 99 %sub = add i32 %xor, -67108864 100 ret i32 %sub 101 } 102 103