218 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4 5define i32 @test1(i32 %X, i8 %A) {6; CHECK-LABEL: @test1(7; CHECK-NEXT: [[SHIFT_UPGRD_1:%.*]] = zext nneg i8 [[A:%.*]] to i328; CHECK-NEXT: [[Y1:%.*]] = lshr i32 [[X:%.*]], [[SHIFT_UPGRD_1]]9; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y1]], 110; CHECK-NEXT: ret i32 [[Z]]11;12 %shift.upgrd.1 = zext i8 %A to i3213 ; can be logical shift.14 %Y = ashr i32 %X, %shift.upgrd.115 %Z = and i32 %Y, 116 ret i32 %Z17}18 19define i32 @test2(i8 %a) {20; CHECK-LABEL: @test2(21; CHECK-NEXT: [[B:%.*]] = zext i8 [[A:%.*]] to i3222; CHECK-NEXT: [[C:%.*]] = add nuw nsw i32 [[B]], 723; CHECK-NEXT: [[D:%.*]] = lshr i32 [[C]], 324; CHECK-NEXT: ret i32 [[D]]25;26 %b = zext i8 %a to i3227 %c = add i32 %b, 728 %d = ashr i32 %c, 329 ret i32 %d30}31 32define i64 @test3(i1 %X, i64 %Y, i1 %Cond) {33; CHECK-LABEL: @test3(34; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]35; CHECK: T:36; CHECK-NEXT: [[X2:%.*]] = sext i1 [[X:%.*]] to i6437; CHECK-NEXT: br label [[C:%.*]]38; CHECK: F:39; CHECK-NEXT: [[Y2:%.*]] = ashr i64 [[Y:%.*]], 6340; CHECK-NEXT: br label [[C]]41; CHECK: C:42; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[X2]], [[T]] ], [ [[Y2]], [[F]] ]43; CHECK-NEXT: ret i64 [[P]]44;45 br i1 %Cond, label %T, label %F46T:47 %X2 = sext i1 %X to i6448 br label %C49F:50 %Y2 = ashr i64 %Y, 6351 br label %C52C:53 %P = phi i64 [%X2, %T], [%Y2, %F]54 %S = ashr i64 %P, 1255 ret i64 %S56}57 58define i64 @test4(i1 %X, i64 %Y, i1 %Cond) {59; CHECK-LABEL: @test4(60; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]61; CHECK: T:62; CHECK-NEXT: [[X2:%.*]] = sext i1 [[X:%.*]] to i6463; CHECK-NEXT: br label [[C:%.*]]64; CHECK: F:65; CHECK-NEXT: [[Y2:%.*]] = ashr i64 [[Y:%.*]], 6366; CHECK-NEXT: br label [[C]]67; CHECK: C:68; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[X2]], [[T]] ], [ [[Y2]], [[F]] ]69; CHECK-NEXT: ret i64 [[P]]70;71 br i1 %Cond, label %T, label %F72T:73 %X2 = sext i1 %X to i6474 br label %C75F:76 %Y2 = ashr i64 %Y, 6377 br label %C78C:79 %P = phi i64 [%X2, %T], [%Y2, %F]80 %R = shl i64 %P, 1281 %S = ashr i64 %R, 1282 ret i64 %S83}84 85; rdar://773298786define i32 @test5(i32 %Y, i1 %c1, i1 %c2, i1 %c3) {87; CHECK-LABEL: @test5(88; CHECK-NEXT: br i1 [[C1:%.*]], label [[A:%.*]], label [[C:%.*]]89; CHECK: A:90; CHECK-NEXT: br i1 [[C2:%.*]], label [[B:%.*]], label [[D:%.*]]91; CHECK: B:92; CHECK-NEXT: br label [[D]]93; CHECK: C:94; CHECK-NEXT: br i1 [[C3:%.*]], label [[D]], label [[E:%.*]]95; CHECK: D:96; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[A]] ], [ 0, [[B]] ], [ [[Y:%.*]], [[C]] ]97; CHECK-NEXT: [[S:%.*]] = ashr i32 [[P]], 1698; CHECK-NEXT: ret i32 [[S]]99; CHECK: E:100; CHECK-NEXT: ret i32 0101;102 br i1 %c1, label %A, label %C103A:104 br i1 %c2, label %B, label %D105B:106 br label %D107C:108 br i1 %c3, label %D, label %E109D:110 %P = phi i32 [0, %A], [0, %B], [%Y, %C]111 %S = ashr i32 %P, 16112 ret i32 %S113E:114 ret i32 0115}116 117; (X >>s C1) >>s C2 --> X >>s (C1 + C2)118 119define i32 @ashr_ashr(i32 %x) {120; CHECK-LABEL: @ashr_ashr(121; CHECK-NEXT: [[SH2:%.*]] = ashr i32 [[X:%.*]], 12122; CHECK-NEXT: ret i32 [[SH2]]123;124 %sh1 = ashr i32 %x, 5125 %sh2 = ashr i32 %sh1, 7126 ret i32 %sh2127}128 129; PR3851130; (X >>s C1) >>s C2 --> X >>s (Bitwidth - 1)131 132define i32 @ashr_overshift(i32 %x) {133; CHECK-LABEL: @ashr_overshift(134; CHECK-NEXT: [[SH2:%.*]] = ashr i32 [[X:%.*]], 31135; CHECK-NEXT: ret i32 [[SH2]]136;137 %sh1 = ashr i32 %x, 15138 %sh2 = ashr i32 %sh1, 17139 ret i32 %sh2140}141 142; (X >>s C1) >>s C2 --> X >>s (C1 + C2)143 144define <2 x i32> @ashr_ashr_splat_vec(<2 x i32> %x) {145; CHECK-LABEL: @ashr_ashr_splat_vec(146; CHECK-NEXT: [[SH2:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 12)147; CHECK-NEXT: ret <2 x i32> [[SH2]]148;149 %sh1 = ashr <2 x i32> %x, <i32 5, i32 5>150 %sh2 = ashr <2 x i32> %sh1, <i32 7, i32 7>151 ret <2 x i32> %sh2152}153 154; (X >>s C1) >>s C2 --> X >>s (Bitwidth - 1)155 156define <2 x i32> @ashr_overshift_splat_vec(<2 x i32> %x) {157; CHECK-LABEL: @ashr_overshift_splat_vec(158; CHECK-NEXT: [[SH2:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 31)159; CHECK-NEXT: ret <2 x i32> [[SH2]]160;161 %sh1 = ashr <2 x i32> %x, <i32 15, i32 15>162 %sh2 = ashr <2 x i32> %sh1, <i32 17, i32 17>163 ret <2 x i32> %sh2164}165 166; ashr (sext X), C --> sext (ashr X, C')167 168define i32 @hoist_ashr_ahead_of_sext_1(i8 %x) {169; CHECK-LABEL: @hoist_ashr_ahead_of_sext_1(170; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 [[X:%.*]], 3171; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP1]] to i32172; CHECK-NEXT: ret i32 [[R]]173;174 %sext = sext i8 %x to i32175 %r = ashr i32 %sext, 3176 ret i32 %r177}178 179; ashr (sext X), C --> sext (ashr X, C')180 181define <2 x i32> @hoist_ashr_ahead_of_sext_1_splat(<2 x i8> %x) {182; CHECK-LABEL: @hoist_ashr_ahead_of_sext_1_splat(183; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 3)184; CHECK-NEXT: [[R:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i32>185; CHECK-NEXT: ret <2 x i32> [[R]]186;187 %sext = sext <2 x i8> %x to <2 x i32>188 %r = ashr <2 x i32> %sext, <i32 3, i32 3>189 ret <2 x i32> %r190}191 192; ashr (sext X), C --> sext (ashr X, C') -- the shift amount must be clamped193 194define i32 @hoist_ashr_ahead_of_sext_2(i8 %x) {195; CHECK-LABEL: @hoist_ashr_ahead_of_sext_2(196; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 [[X:%.*]], 7197; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP1]] to i32198; CHECK-NEXT: ret i32 [[R]]199;200 %sext = sext i8 %x to i32201 %r = ashr i32 %sext, 8202 ret i32 %r203}204 205; ashr (sext X), C --> sext (ashr X, C') -- the shift amount must be clamped206 207define <2 x i32> @hoist_ashr_ahead_of_sext_2_splat(<2 x i8> %x) {208; CHECK-LABEL: @hoist_ashr_ahead_of_sext_2_splat(209; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7)210; CHECK-NEXT: [[R:%.*]] = sext <2 x i8> [[TMP1]] to <2 x i32>211; CHECK-NEXT: ret <2 x i32> [[R]]212;213 %sext = sext <2 x i8> %x to <2 x i32>214 %r = ashr <2 x i32> %sext, <i32 8, i32 8>215 ret <2 x i32> %r216}217 218