1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i32 @t0(i64 %x) { 5; CHECK-LABEL: @t0( 6; CHECK-NEXT: [[T0_NEG:%.*]] = ashr i64 [[X:%.*]], 63 7; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i64 [[T0_NEG]] to i32 8; CHECK-NEXT: ret i32 [[T1_NEG]] 9; 10 %t0 = lshr i64 %x, 63 11 %t1 = trunc i64 %t0 to i32 12 %r = sub i32 0, %t1 13 ret i32 %r 14} 15define i32 @t1_exact(i64 %x) { 16; CHECK-LABEL: @t1_exact( 17; CHECK-NEXT: [[T0_NEG:%.*]] = ashr exact i64 [[X:%.*]], 63 18; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i64 [[T0_NEG]] to i32 19; CHECK-NEXT: ret i32 [[T1_NEG]] 20; 21 %t0 = lshr exact i64 %x, 63 22 %t1 = trunc i64 %t0 to i32 23 %r = sub i32 0, %t1 24 ret i32 %r 25} 26define i32 @t2(i64 %x) { 27; CHECK-LABEL: @t2( 28; CHECK-NEXT: [[T0_NEG:%.*]] = lshr i64 [[X:%.*]], 63 29; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i64 [[T0_NEG]] to i32 30; CHECK-NEXT: ret i32 [[T1_NEG]] 31; 32 %t0 = ashr i64 %x, 63 33 %t1 = trunc i64 %t0 to i32 34 %r = sub i32 0, %t1 35 ret i32 %r 36} 37define i32 @t3_exact(i64 %x) { 38; CHECK-LABEL: @t3_exact( 39; CHECK-NEXT: [[T0_NEG:%.*]] = lshr exact i64 [[X:%.*]], 63 40; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i64 [[T0_NEG]] to i32 41; CHECK-NEXT: ret i32 [[T1_NEG]] 42; 43 %t0 = ashr exact i64 %x, 63 44 %t1 = trunc i64 %t0 to i32 45 %r = sub i32 0, %t1 46 ret i32 %r 47} 48 49define <2 x i32> @t4(<2 x i64> %x) { 50; CHECK-LABEL: @t4( 51; CHECK-NEXT: [[T0_NEG:%.*]] = ashr <2 x i64> [[X:%.*]], <i64 63, i64 63> 52; CHECK-NEXT: [[T1_NEG:%.*]] = trunc <2 x i64> [[T0_NEG]] to <2 x i32> 53; CHECK-NEXT: ret <2 x i32> [[T1_NEG]] 54; 55 %t0 = lshr <2 x i64> %x, <i64 63, i64 63> 56 %t1 = trunc <2 x i64> %t0 to <2 x i32> 57 %r = sub <2 x i32> zeroinitializer, %t1 58 ret <2 x i32> %r 59} 60 61define <2 x i32> @t5(<2 x i64> %x) { 62; CHECK-LABEL: @t5( 63; CHECK-NEXT: [[T0:%.*]] = lshr <2 x i64> [[X:%.*]], <i64 63, i64 undef> 64; CHECK-NEXT: [[T1:%.*]] = trunc <2 x i64> [[T0]] to <2 x i32> 65; CHECK-NEXT: [[R:%.*]] = sub <2 x i32> <i32 0, i32 undef>, [[T1]] 66; CHECK-NEXT: ret <2 x i32> [[R]] 67; 68 %t0 = lshr <2 x i64> %x, <i64 63, i64 undef> 69 %t1 = trunc <2 x i64> %t0 to <2 x i32> 70 %r = sub <2 x i32> <i32 0, i32 undef>, %t1 71 ret <2 x i32> %r 72} 73 74declare void @use64(i64) 75declare void @use32(i32) 76 77define i32 @t6(i64 %x) { 78; CHECK-LABEL: @t6( 79; CHECK-NEXT: [[T0_NEG:%.*]] = ashr i64 [[X:%.*]], 63 80; CHECK-NEXT: [[T0:%.*]] = lshr i64 [[X]], 63 81; CHECK-NEXT: call void @use64(i64 [[T0]]) 82; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i64 [[T0_NEG]] to i32 83; CHECK-NEXT: ret i32 [[T1_NEG]] 84; 85 %t0 = lshr i64 %x, 63 86 call void @use64(i64 %t0) 87 %t1 = trunc i64 %t0 to i32 88 %r = sub i32 0, %t1 89 ret i32 %r 90} 91 92define i32 @n7(i64 %x) { 93; CHECK-LABEL: @n7( 94; CHECK-NEXT: [[T0:%.*]] = lshr i64 [[X:%.*]], 63 95; CHECK-NEXT: [[T1:%.*]] = trunc i64 [[T0]] to i32 96; CHECK-NEXT: call void @use32(i32 [[T1]]) 97; CHECK-NEXT: [[R:%.*]] = sub nsw i32 0, [[T1]] 98; CHECK-NEXT: ret i32 [[R]] 99; 100 %t0 = lshr i64 %x, 63 101 %t1 = trunc i64 %t0 to i32 102 call void @use32(i32 %t1) 103 %r = sub i32 0, %t1 104 ret i32 %r 105} 106 107define i32 @n8(i64 %x) { 108; CHECK-LABEL: @n8( 109; CHECK-NEXT: [[T0:%.*]] = lshr i64 [[X:%.*]], 63 110; CHECK-NEXT: call void @use64(i64 [[T0]]) 111; CHECK-NEXT: [[T1:%.*]] = trunc i64 [[T0]] to i32 112; CHECK-NEXT: call void @use32(i32 [[T1]]) 113; CHECK-NEXT: [[R:%.*]] = sub nsw i32 0, [[T1]] 114; CHECK-NEXT: ret i32 [[R]] 115; 116 %t0 = lshr i64 %x, 63 117 call void @use64(i64 %t0) 118 %t1 = trunc i64 %t0 to i32 119 call void @use32(i32 %t1) 120 %r = sub i32 0, %t1 121 ret i32 %r 122} 123 124define i32 @n9(i64 %x) { 125; CHECK-LABEL: @n9( 126; CHECK-NEXT: [[T0:%.*]] = lshr i64 [[X:%.*]], 62 127; CHECK-NEXT: [[T1:%.*]] = trunc i64 [[T0]] to i32 128; CHECK-NEXT: [[R:%.*]] = sub nsw i32 0, [[T1]] 129; CHECK-NEXT: ret i32 [[R]] 130; 131 %t0 = lshr i64 %x, 62 132 %t1 = trunc i64 %t0 to i32 133 %r = sub i32 0, %t1 134 ret i32 %r 135} 136 137define i32 @n10(i64 %x) { 138; CHECK-LABEL: @n10( 139; CHECK-NEXT: [[T0_NEG:%.*]] = ashr i64 [[X:%.*]], 63 140; CHECK-NEXT: [[T1_NEG:%.*]] = trunc i64 [[T0_NEG]] to i32 141; CHECK-NEXT: [[R:%.*]] = add i32 [[T1_NEG]], 1 142; CHECK-NEXT: ret i32 [[R]] 143; 144 %t0 = lshr i64 %x, 63 145 %t1 = trunc i64 %t0 to i32 146 %r = sub i32 1, %t1 147 ret i32 %r 148} 149