brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.5 KiB · 27b6ae8 Raw
950 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -passes=separate-const-offset-from-gep < %s | FileCheck %s3 4declare void @use.i32(i32 noundef)5declare void @allow.undef.use.i32(i32)6 7declare void @use.v2i32(<2 x i32> noundef)8declare void @allow.undef.use.v2i32(<2 x i32>)9 10declare void @use.i64(i64 noundef)11 12; Should fold out the 64-bit add13define i64 @add_sext__dominating_add_nsw(i32 %arg0, i32 %arg1) {14; CHECK-LABEL: define i64 @add_sext__dominating_add_nsw15; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] {16; CHECK-NEXT:  entry:17; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]18; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext i32 [[ADD_NSW]] to i6419; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])20; CHECK-NEXT:    ret i64 [[ADD_SEXT]]21;22entry:23  %add.nsw = add nsw i32 %arg0, %arg124  %arg0.sext = sext i32 %arg0 to i6425  %arg1.sext = sext i32 %arg1 to i6426  %add.sext = add i64 %arg0.sext, %arg1.sext27  call void @use.i32(i32 %add.nsw)28  ret i64 %add.sext29}30 31; Should fold out the 64-bit sub32define i64 @sub_sext__dominating_sub_nsw(i32 %arg0, i32 %arg1) {33; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nsw34; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {35; CHECK-NEXT:  entry:36; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]37; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sext i32 [[SUB_NSW]] to i6438; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])39; CHECK-NEXT:    ret i64 [[SUB_SEXT]]40;41entry:42  %sub.nsw = sub nsw i32 %arg0, %arg143  %arg0.sext = sext i32 %arg0 to i6444  %arg1.sext = sext i32 %arg1 to i6445  %sub.sext = sub i64 %arg0.sext, %arg1.sext46  call void @use.i32(i32 %sub.nsw)47  ret i64 %sub.sext48}49 50; Should fold out the 64-bit add. The 64-bit add has commuted operands51; compared to the original.52define i64 @add_sext__dominating_add_nsw_commuted(i32 %arg0, i32 %arg1) {53; CHECK-LABEL: define i64 @add_sext__dominating_add_nsw_commuted54; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {55; CHECK-NEXT:  entry:56; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]57; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext i32 [[ADD_NSW]] to i6458; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])59; CHECK-NEXT:    ret i64 [[ADD_SEXT]]60;61entry:62  %add.nsw = add nsw i32 %arg0, %arg163  %arg0.sext = sext i32 %arg0 to i6464  %arg1.sext = sext i32 %arg1 to i6465  %add.sext = add i64 %arg1.sext, %arg0.sext66  call void @use.i32(i32 %add.nsw)67  ret i64 %add.sext68}69 70; The second sub has commuted operands71define i64 @sub_sext__dominating_sub_nsw_commuted(i32 %arg0, i32 %arg1) {72; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nsw_commuted73; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {74; CHECK-NEXT:  entry:75; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]76; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i6477; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i6478; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG1_SEXT]], [[ARG0_SEXT]]79; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])80; CHECK-NEXT:    ret i64 [[SUB_SEXT]]81;82entry:83  %sub.nsw = sub nsw i32 %arg0, %arg184  %arg0.sext = sext i32 %arg0 to i6485  %arg1.sext = sext i32 %arg1 to i6486  %sub.sext = sub i64 %arg1.sext, %arg0.sext87  call void @use.i32(i32 %sub.nsw)88  ret i64 %sub.sext89}90 91; Missing nsw on the add i32, can't do anything92define i64 @add_sext__dominating_add(i32 %arg0, i32 %arg1) {93; CHECK-LABEL: define i64 @add_sext__dominating_add94; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {95; CHECK-NEXT:  entry:96; CHECK-NEXT:    [[ADD_NSW:%.*]] = add i32 [[ARG0]], [[ARG1]]97; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i6498; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i6499; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]100; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])101; CHECK-NEXT:    ret i64 [[ADD_SEXT]]102;103entry:104  %add.nsw = add i32 %arg0, %arg1105  %arg0.sext = sext i32 %arg0 to i64106  %arg1.sext = sext i32 %arg1 to i64107  %add.sext = add i64 %arg0.sext, %arg1.sext108  call void @use.i32(i32 %add.nsw)109  ret i64 %add.sext110}111 112; Missing nsw on the sub i32, can't do anything113define i64 @sub_sext__dominating_sub(i32 %arg0, i32 %arg1) {114; CHECK-LABEL: define i64 @sub_sext__dominating_sub115; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {116; CHECK-NEXT:  entry:117; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub i32 [[ARG0]], [[ARG1]]118; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64119; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64120; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]121; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])122; CHECK-NEXT:    ret i64 [[SUB_SEXT]]123;124entry:125  %sub.nsw = sub i32 %arg0, %arg1126  %arg0.sext = sext i32 %arg0 to i64127  %arg1.sext = sext i32 %arg1 to i64128  %sub.sext = sub i64 %arg0.sext, %arg1.sext129  call void @use.i32(i32 %sub.nsw)130  ret i64 %sub.sext131}132 133; The use of the 32-bit add allows poison, so can't fold.134define i64 @add_sext__dominating_add_nsw_defined(i32 %arg0, i32 %arg1) {135; CHECK-LABEL: define i64 @add_sext__dominating_add_nsw_defined136; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {137; CHECK-NEXT:  entry:138; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]139; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64140; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64141; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]142; CHECK-NEXT:    call void @allow.undef.use.i32(i32 [[ADD_NSW]])143; CHECK-NEXT:    ret i64 [[ADD_SEXT]]144;145entry:146  %add.nsw = add nsw i32 %arg0, %arg1147  %arg0.sext = sext i32 %arg0 to i64148  %arg1.sext = sext i32 %arg1 to i64149  %add.sext = add i64 %arg0.sext, %arg1.sext150  call void @allow.undef.use.i32(i32 %add.nsw)151  ret i64 %add.sext152}153 154; The use of the 32-bit sub allows poison, so can't fold.155define i64 @sub_sext__dominating_sub_nsw_defined(i32 %arg0, i32 %arg1) {156; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nsw_defined157; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {158; CHECK-NEXT:  entry:159; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]160; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64161; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64162; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]163; CHECK-NEXT:    call void @allow.undef.use.i32(i32 [[SUB_NSW]])164; CHECK-NEXT:    ret i64 [[SUB_SEXT]]165;166entry:167  %sub.nsw = sub nsw i32 %arg0, %arg1168  %arg0.sext = sext i32 %arg0 to i64169  %arg1.sext = sext i32 %arg1 to i64170  %sub.sext = sub i64 %arg0.sext, %arg1.sext171  call void @allow.undef.use.i32(i32 %sub.nsw)172  ret i64 %sub.sext173}174 175define i64 @add_sext__dominating_add_nsw_multi_use_sext0(i32 %arg0, i32 %arg1) {176; CHECK-LABEL: define i64 @add_sext__dominating_add_nsw_multi_use_sext0177; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {178; CHECK-NEXT:  entry:179; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]180; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64181; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64182; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]183; CHECK-NEXT:    call void @use.i64(i64 [[ARG0_SEXT]])184; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])185; CHECK-NEXT:    ret i64 [[ADD_SEXT]]186;187entry:188  %add.nsw = add nsw i32 %arg0, %arg1189  %arg0.sext = sext i32 %arg0 to i64190  %arg1.sext = sext i32 %arg1 to i64191  %add.sext = add i64 %arg0.sext, %arg1.sext192  call void @use.i64(i64 %arg0.sext)193  call void @use.i32(i32 %add.nsw)194  ret i64 %add.sext195}196 197define i64 @add_sext__dominating_add_nsw_multi_use_sext1(i32 %arg0, i32 %arg1) {198; CHECK-LABEL: define i64 @add_sext__dominating_add_nsw_multi_use_sext1199; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {200; CHECK-NEXT:  entry:201; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]202; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64203; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64204; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]205; CHECK-NEXT:    call void @use.i64(i64 [[ARG1_SEXT]])206; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])207; CHECK-NEXT:    ret i64 [[ADD_SEXT]]208;209entry:210  %add.nsw = add nsw i32 %arg0, %arg1211  %arg0.sext = sext i32 %arg0 to i64212  %arg1.sext = sext i32 %arg1 to i64213  %add.sext = add i64 %arg0.sext, %arg1.sext214  call void @use.i64(i64 %arg1.sext)215  call void @use.i32(i32 %add.nsw)216  ret i64 %add.sext217}218 219define i64 @sub_sext__dominating_sub_nsw_multi_use_sext0(i32 %arg0, i32 %arg1) {220; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nsw_multi_use_sext0221; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {222; CHECK-NEXT:  entry:223; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]224; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64225; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64226; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]227; CHECK-NEXT:    call void @use.i64(i64 [[ARG0_SEXT]])228; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])229; CHECK-NEXT:    ret i64 [[SUB_SEXT]]230;231entry:232  %sub.nsw = sub nsw i32 %arg0, %arg1233  %arg0.sext = sext i32 %arg0 to i64234  %arg1.sext = sext i32 %arg1 to i64235  %sub.sext = sub i64 %arg0.sext, %arg1.sext236  call void @use.i64(i64 %arg0.sext)237  call void @use.i32(i32 %sub.nsw)238  ret i64 %sub.sext239}240 241define i64 @sub_sext__dominating_sub_nsw_multi_use_sext1(i32 %arg0, i32 %arg1) {242; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nsw_multi_use_sext1243; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {244; CHECK-NEXT:  entry:245; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]246; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64247; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64248; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]249; CHECK-NEXT:    call void @use.i64(i64 [[ARG1_SEXT]])250; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])251; CHECK-NEXT:    ret i64 [[SUB_SEXT]]252;253entry:254  %sub.nsw = sub nsw i32 %arg0, %arg1255  %arg0.sext = sext i32 %arg0 to i64256  %arg1.sext = sext i32 %arg1 to i64257  %sub.sext = sub i64 %arg0.sext, %arg1.sext258  call void @use.i64(i64 %arg1.sext)259  call void @use.i32(i32 %sub.nsw)260  ret i64 %sub.sext261}262 263; --------------------------------------------------------------------264; Vector handling265; --------------------------------------------------------------------266 267; Should fold out the 64-bit add268define <2 x i64> @add_sext__dominating_add_nsw_vector(<2 x i32> %arg0, <2 x i32> %arg1) {269; CHECK-LABEL: define <2 x i64> @add_sext__dominating_add_nsw_vector270; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {271; CHECK-NEXT:  entry:272; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw <2 x i32> [[ARG0]], [[ARG1]]273; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext <2 x i32> [[ADD_NSW]] to <2 x i64>274; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[ADD_NSW]])275; CHECK-NEXT:    ret <2 x i64> [[ADD_SEXT]]276;277entry:278  %add.nsw = add nsw <2 x i32> %arg0, %arg1279  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>280  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>281  %add.sext = add <2 x i64> %arg0.sext, %arg1.sext282  call void @use.v2i32(<2 x i32> %add.nsw)283  ret <2 x i64> %add.sext284}285 286; Should fold out the 64-bit sub287define <2 x i64> @sub_sext__dominating_sub_nsw_vector(<2 x i32> %arg0, <2 x i32> %arg1) {288; CHECK-LABEL: define <2 x i64> @sub_sext__dominating_sub_nsw_vector289; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {290; CHECK-NEXT:  entry:291; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw <2 x i32> [[ARG0]], [[ARG1]]292; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sext <2 x i32> [[SUB_NSW]] to <2 x i64>293; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[SUB_NSW]])294; CHECK-NEXT:    ret <2 x i64> [[SUB_SEXT]]295;296entry:297  %sub.nsw = sub nsw <2 x i32> %arg0, %arg1298  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>299  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>300  %sub.sext = sub <2 x i64> %arg0.sext, %arg1.sext301  call void @use.v2i32(<2 x i32> %sub.nsw)302  ret <2 x i64> %sub.sext303}304 305; Should fold out the 64-bit add. The 64-bit add has commuted operands306; compared to the original.307define <2 x i64> @add_sext__dominating_add_nsw_commuted_vector(<2 x i32> %arg0, <2 x i32> %arg1) {308; CHECK-LABEL: define <2 x i64> @add_sext__dominating_add_nsw_commuted_vector309; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {310; CHECK-NEXT:  entry:311; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw <2 x i32> [[ARG0]], [[ARG1]]312; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext <2 x i32> [[ADD_NSW]] to <2 x i64>313; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[ADD_NSW]])314; CHECK-NEXT:    ret <2 x i64> [[ADD_SEXT]]315;316entry:317  %add.nsw = add nsw <2 x i32> %arg0, %arg1318  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>319  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>320  %add.sext = add <2 x i64> %arg1.sext, %arg0.sext321  call void @use.v2i32(<2 x i32> %add.nsw)322  ret <2 x i64> %add.sext323}324 325; The second sub has commuted operands326define <2 x i64> @sub_sext__dominating_sub_nsw_commuted_vector(<2 x i32> %arg0, <2 x i32> %arg1) {327; CHECK-LABEL: define <2 x i64> @sub_sext__dominating_sub_nsw_commuted_vector328; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {329; CHECK-NEXT:  entry:330; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw <2 x i32> [[ARG0]], [[ARG1]]331; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext <2 x i32> [[ARG0]] to <2 x i64>332; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext <2 x i32> [[ARG1]] to <2 x i64>333; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub <2 x i64> [[ARG1_SEXT]], [[ARG0_SEXT]]334; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[SUB_NSW]])335; CHECK-NEXT:    ret <2 x i64> [[SUB_SEXT]]336;337entry:338  %sub.nsw = sub nsw <2 x i32> %arg0, %arg1339  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>340  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>341  %sub.sext = sub <2 x i64> %arg1.sext, %arg0.sext342  call void @use.v2i32(<2 x i32> %sub.nsw)343  ret <2 x i64> %sub.sext344}345 346; Missing nsw on the add <2 x i32>, can't do anything347define <2 x i64> @add_sext__dominating_add_vector(<2 x i32> %arg0, <2 x i32> %arg1) {348; CHECK-LABEL: define <2 x i64> @add_sext__dominating_add_vector349; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {350; CHECK-NEXT:  entry:351; CHECK-NEXT:    [[ADD_NSW:%.*]] = add <2 x i32> [[ARG0]], [[ARG1]]352; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext <2 x i32> [[ARG0]] to <2 x i64>353; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext <2 x i32> [[ARG1]] to <2 x i64>354; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add <2 x i64> [[ARG0_SEXT]], [[ARG1_SEXT]]355; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[ADD_NSW]])356; CHECK-NEXT:    ret <2 x i64> [[ADD_SEXT]]357;358entry:359  %add.nsw = add <2 x i32> %arg0, %arg1360  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>361  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>362  %add.sext = add <2 x i64> %arg0.sext, %arg1.sext363  call void @use.v2i32(<2 x i32> %add.nsw)364  ret <2 x i64> %add.sext365}366 367; Missing nsw on the sub <2 x i32>, can't do anything368define <2 x i64> @sub_sext__dominating_sub_vector(<2 x i32> %arg0, <2 x i32> %arg1) {369; CHECK-LABEL: define <2 x i64> @sub_sext__dominating_sub_vector370; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {371; CHECK-NEXT:  entry:372; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub <2 x i32> [[ARG0]], [[ARG1]]373; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext <2 x i32> [[ARG0]] to <2 x i64>374; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext <2 x i32> [[ARG1]] to <2 x i64>375; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub <2 x i64> [[ARG0_SEXT]], [[ARG1_SEXT]]376; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[SUB_NSW]])377; CHECK-NEXT:    ret <2 x i64> [[SUB_SEXT]]378;379entry:380  %sub.nsw = sub <2 x i32> %arg0, %arg1381  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>382  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>383  %sub.sext = sub <2 x i64> %arg0.sext, %arg1.sext384  call void @use.v2i32(<2 x i32> %sub.nsw)385  ret <2 x i64> %sub.sext386}387 388; The use of the 32-bit add allows poison, so can't fold.389define <2 x i64> @add_sext__dominating_add_nsw_defined_vector(<2 x i32> %arg0, <2 x i32> %arg1) {390; CHECK-LABEL: define <2 x i64> @add_sext__dominating_add_nsw_defined_vector391; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {392; CHECK-NEXT:  entry:393; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw <2 x i32> [[ARG0]], [[ARG1]]394; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext <2 x i32> [[ARG0]] to <2 x i64>395; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext <2 x i32> [[ARG1]] to <2 x i64>396; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add <2 x i64> [[ARG0_SEXT]], [[ARG1_SEXT]]397; CHECK-NEXT:    call void @allow.undef.use.v2i32(<2 x i32> [[ADD_NSW]])398; CHECK-NEXT:    ret <2 x i64> [[ADD_SEXT]]399;400entry:401  %add.nsw = add nsw <2 x i32> %arg0, %arg1402  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>403  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>404  %add.sext = add <2 x i64> %arg0.sext, %arg1.sext405  call void @allow.undef.use.v2i32(<2 x i32> %add.nsw)406  ret <2 x i64> %add.sext407}408 409; The use of the 32-bit sub allows poison, so can't fold.410define <2 x i64> @sub_sext__dominating_sub_nsw_defined_vector(<2 x i32> %arg0, <2 x i32> %arg1) {411; CHECK-LABEL: define <2 x i64> @sub_sext__dominating_sub_nsw_defined_vector412; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {413; CHECK-NEXT:  entry:414; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw <2 x i32> [[ARG0]], [[ARG1]]415; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext <2 x i32> [[ARG0]] to <2 x i64>416; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext <2 x i32> [[ARG1]] to <2 x i64>417; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub <2 x i64> [[ARG0_SEXT]], [[ARG1_SEXT]]418; CHECK-NEXT:    call void @allow.undef.use.v2i32(<2 x i32> [[SUB_NSW]])419; CHECK-NEXT:    ret <2 x i64> [[SUB_SEXT]]420;421entry:422  %sub.nsw = sub nsw <2 x i32> %arg0, %arg1423  %arg0.sext = sext <2 x i32> %arg0 to <2 x i64>424  %arg1.sext = sext <2 x i32> %arg1 to <2 x i64>425  %sub.sext = sub <2 x i64> %arg0.sext, %arg1.sext426  call void @allow.undef.use.v2i32(<2 x i32> %sub.nsw)427  ret <2 x i64> %sub.sext428}429 430; --------------------------------------------------------------------431; Zext x nsw432; --------------------------------------------------------------------433 434; Want sext, not zext435define i64 @add_zext__dominating_add_nsw(i32 %arg0, i32 %arg1) {436; CHECK-LABEL: define i64 @add_zext__dominating_add_nsw437; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {438; CHECK-NEXT:  entry:439; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]440; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = zext i32 [[ARG0]] to i64441; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = zext i32 [[ARG1]] to i64442; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]443; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])444; CHECK-NEXT:    ret i64 [[ADD_SEXT]]445;446entry:447  %add.nsw = add nsw i32 %arg0, %arg1448  %arg0.sext = zext i32 %arg0 to i64449  %arg1.sext = zext i32 %arg1 to i64450  %add.sext = add i64 %arg0.sext, %arg1.sext451  call void @use.i32(i32 %add.nsw)452  ret i64 %add.sext453}454 455; Want sext, not zext456define i64 @sub_zext__dominating_add_nsw(i32 %arg0, i32 %arg1) {457; CHECK-LABEL: define i64 @sub_zext__dominating_add_nsw458; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {459; CHECK-NEXT:  entry:460; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]461; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = zext i32 [[ARG0]] to i64462; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = zext i32 [[ARG1]] to i64463; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]464; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])465; CHECK-NEXT:    ret i64 [[SUB_SEXT]]466;467entry:468  %sub.nsw = sub nsw i32 %arg0, %arg1469  %arg0.sext = zext i32 %arg0 to i64470  %arg1.sext = zext i32 %arg1 to i64471  %sub.sext = sub i64 %arg0.sext, %arg1.sext472  call void @use.i32(i32 %sub.nsw)473  ret i64 %sub.sext474}475 476; --------------------------------------------------------------------477; sext x nuw478; --------------------------------------------------------------------479 480; Want nsw, not nuw481define i64 @add_sext__dominating_add_nuw(i32 %arg0, i32 %arg1) {482; CHECK-LABEL: define i64 @add_sext__dominating_add_nuw483; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {484; CHECK-NEXT:  entry:485; CHECK-NEXT:    [[ADD_NUW:%.*]] = add nuw i32 [[ARG0]], [[ARG1]]486; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64487; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64488; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]489; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW]])490; CHECK-NEXT:    ret i64 [[ADD_SEXT]]491;492entry:493  %add.nuw = add nuw i32 %arg0, %arg1494  %arg0.sext = sext i32 %arg0 to i64495  %arg1.sext = sext i32 %arg1 to i64496  %add.sext = add i64 %arg0.sext, %arg1.sext497  call void @use.i32(i32 %add.nuw)498  ret i64 %add.sext499}500 501; Want nsw, not nuw502define i64 @sub_sext__dominating_sub_nuw(i32 %arg0, i32 %arg1) {503; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nuw504; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {505; CHECK-NEXT:  entry:506; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw i32 [[ARG0]], [[ARG1]]507; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64508; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64509; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]510; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NUW]])511; CHECK-NEXT:    ret i64 [[SUB_SEXT]]512;513entry:514  %sub.nuw = sub nuw i32 %arg0, %arg1515  %arg0.sext = sext i32 %arg0 to i64516  %arg1.sext = sext i32 %arg1 to i64517  %sub.sext = sub i64 %arg0.sext, %arg1.sext518  call void @use.i32(i32 %sub.nuw)519  ret i64 %sub.sext520}521 522; --------------------------------------------------------------------523; Misc negative tests524; --------------------------------------------------------------------525 526; Opcode mismatch 1527define i64 @add_sext__dominating_sub_nsw(i32 %arg0, i32 %arg1) {528; CHECK-LABEL: define i64 @add_sext__dominating_sub_nsw529; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {530; CHECK-NEXT:  entry:531; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]532; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64533; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64534; CHECK-NEXT:    [[SUB_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]535; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])536; CHECK-NEXT:    ret i64 [[SUB_SEXT]]537;538entry:539  %sub.nsw = sub nsw i32 %arg0, %arg1540  %arg0.sext = sext i32 %arg0 to i64541  %arg1.sext = sext i32 %arg1 to i64542  %sub.sext = add i64 %arg0.sext, %arg1.sext543  call void @use.i32(i32 %sub.nsw)544  ret i64 %sub.sext545}546 547; Opcode mismatch 2548define i64 @sub_sext__dominating_add_nsw(i32 %arg0, i32 %arg1) {549; CHECK-LABEL: define i64 @sub_sext__dominating_add_nsw550; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {551; CHECK-NEXT:  entry:552; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]553; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64554; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64555; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]556; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])557; CHECK-NEXT:    ret i64 [[SUB_SEXT]]558;559entry:560  %add.nsw = add nsw i32 %arg0, %arg1561  %arg0.sext = sext i32 %arg0 to i64562  %arg1.sext = sext i32 %arg1 to i64563  %sub.sext = sub i64 %arg0.sext, %arg1.sext564  call void @use.i32(i32 %add.nsw)565  ret i64 %sub.sext566}567 568; Both nsw add and sub coexist for the same inputs569define void @add_sext__dominating_add_nsw_sub_nsw(i32 %arg0, i32 %arg1) {570; CHECK-LABEL: define void @add_sext__dominating_add_nsw_sub_nsw571; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {572; CHECK-NEXT:  entry:573; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]574; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]575; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64576; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64577; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext i32 [[ADD_NSW]] to i64578; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]579; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])580; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])581; CHECK-NEXT:    call void @use.i64(i64 [[ADD_SEXT]])582; CHECK-NEXT:    call void @use.i64(i64 [[SUB_SEXT]])583; CHECK-NEXT:    ret void584;585entry:586  %add.nsw = add nsw i32 %arg0, %arg1587  %sub.nsw = sub nsw i32 %arg0, %arg1588  %arg0.sext = sext i32 %arg0 to i64589  %arg1.sext = sext i32 %arg1 to i64590  %add.sext = add i64 %arg0.sext, %arg1.sext591  %sub.sext = sub i64 %arg0.sext, %arg1.sext592  call void @use.i32(i32 %add.nsw)593  call void @use.i32(i32 %sub.nsw)594  call void @use.i64(i64 %add.sext)595  call void @use.i64(i64 %sub.sext)596  ret void597}598 599; Both nsw add and sub coexist for the same inputs, but commuted600define void @add_sext__dominating_add_nsw_sub_nsw_swapped(i32 %arg0, i32 %arg1) {601; CHECK-LABEL: define void @add_sext__dominating_add_nsw_sub_nsw_swapped602; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {603; CHECK-NEXT:  entry:604; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]605; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG1]], [[ARG0]]606; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64607; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64608; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext i32 [[ADD_NSW]] to i64609; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG1_SEXT]], [[ARG0_SEXT]]610; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])611; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])612; CHECK-NEXT:    call void @use.i64(i64 [[ADD_SEXT]])613; CHECK-NEXT:    call void @use.i64(i64 [[SUB_SEXT]])614; CHECK-NEXT:    ret void615;616entry:617  %add.nsw = add nsw i32 %arg0, %arg1618  %sub.nsw = sub nsw i32 %arg1, %arg0619  %arg0.sext = sext i32 %arg0 to i64620  %arg1.sext = sext i32 %arg1 to i64621  %add.sext = add i64 %arg0.sext, %arg1.sext622  %sub.sext = sub i64 %arg1.sext, %arg0.sext623  call void @use.i32(i32 %add.nsw)624  call void @use.i32(i32 %sub.nsw)625  call void @use.i64(i64 %add.sext)626  call void @use.i64(i64 %sub.sext)627  ret void628}629 630; --------------------------------------------------------------------631; zext x nuw632; --------------------------------------------------------------------633 634; Should fold out the add i64635define i64 @add_zext__dominating_add_nuw(i32 %arg0, i32 %arg1) {636; CHECK-LABEL: define i64 @add_zext__dominating_add_nuw637; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {638; CHECK-NEXT:  entry:639; CHECK-NEXT:    [[ADD_NUW:%.*]] = add nuw i32 [[ARG0]], [[ARG1]]640; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64641; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64642; CHECK-NEXT:    [[ADD_ZEXT:%.*]] = add i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]643; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW]])644; CHECK-NEXT:    ret i64 [[ADD_ZEXT]]645;646entry:647  %add.nuw = add nuw i32 %arg0, %arg1648  %arg0.zext = zext i32 %arg0 to i64649  %arg1.zext = zext i32 %arg1 to i64650  %add.zext = add i64 %arg0.zext, %arg1.zext651  call void @use.i32(i32 %add.nuw)652  ret i64 %add.zext653}654 655; Should fold out the sub i64656define i64 @sub_zext__dominating_sub_nuw(i32 %arg0, i32 %arg1) {657; CHECK-LABEL: define i64 @sub_zext__dominating_sub_nuw658; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {659; CHECK-NEXT:  entry:660; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw i32 [[ARG0]], [[ARG1]]661; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64662; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64663; CHECK-NEXT:    [[SUB_ZEXT:%.*]] = sub i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]664; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NUW]])665; CHECK-NEXT:    ret i64 [[SUB_ZEXT]]666;667entry:668  %sub.nuw = sub nuw i32 %arg0, %arg1669  %arg0.zext = zext i32 %arg0 to i64670  %arg1.zext = zext i32 %arg1 to i64671  %sub.zext = sub i64 %arg0.zext, %arg1.zext672  call void @use.i32(i32 %sub.nuw)673  ret i64 %sub.zext674}675 676; Should fold out the add <2 x i64>677define <2 x i64> @add_zext__dominating_add_nuw_vector(<2 x i32> %arg0, <2 x i32> %arg1) {678; CHECK-LABEL: define <2 x i64> @add_zext__dominating_add_nuw_vector679; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {680; CHECK-NEXT:  entry:681; CHECK-NEXT:    [[ADD_NUW:%.*]] = add nuw <2 x i32> [[ARG0]], [[ARG1]]682; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext <2 x i32> [[ARG0]] to <2 x i64>683; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext <2 x i32> [[ARG1]] to <2 x i64>684; CHECK-NEXT:    [[ADD_ZEXT:%.*]] = add <2 x i64> [[ARG0_ZEXT]], [[ARG1_ZEXT]]685; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[ADD_NUW]])686; CHECK-NEXT:    ret <2 x i64> [[ADD_ZEXT]]687;688entry:689  %add.nuw = add nuw <2 x i32> %arg0, %arg1690  %arg0.zext = zext <2 x i32> %arg0 to <2 x i64>691  %arg1.zext = zext <2 x i32> %arg1 to <2 x i64>692  %add.zext = add <2 x i64> %arg0.zext, %arg1.zext693  call void @use.v2i32(<2 x i32> %add.nuw)694  ret <2 x i64> %add.zext695}696 697; Should fold out the sub <2 x i64>698define <2 x i64> @sub_zext__dominating_sub_nuw_vector(<2 x i32> %arg0, <2 x i32> %arg1) {699; CHECK-LABEL: define <2 x i64> @sub_zext__dominating_sub_nuw_vector700; CHECK-SAME: (<2 x i32> [[ARG0:%.*]], <2 x i32> [[ARG1:%.*]]) #[[ATTR0]] {701; CHECK-NEXT:  entry:702; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw <2 x i32> [[ARG0]], [[ARG1]]703; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext <2 x i32> [[ARG0]] to <2 x i64>704; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext <2 x i32> [[ARG1]] to <2 x i64>705; CHECK-NEXT:    [[SUB_ZEXT:%.*]] = sub <2 x i64> [[ARG0_ZEXT]], [[ARG1_ZEXT]]706; CHECK-NEXT:    call void @use.v2i32(<2 x i32> [[SUB_NUW]])707; CHECK-NEXT:    ret <2 x i64> [[SUB_ZEXT]]708;709entry:710  %sub.nuw = sub nuw <2 x i32> %arg0, %arg1711  %arg0.zext = zext <2 x i32> %arg0 to <2 x i64>712  %arg1.zext = zext <2 x i32> %arg1 to <2 x i64>713  %sub.zext = sub <2 x i64> %arg0.zext, %arg1.zext714  call void @use.v2i32(<2 x i32> %sub.nuw)715  ret <2 x i64> %sub.zext716}717 718; Both nuw and nsw exist719define void @add_zext_add_sext__dominating_add_nuw_add_nsw(i32 %arg0, i32 %arg1) {720; CHECK-LABEL: define void @add_zext_add_sext__dominating_add_nuw_add_nsw721; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {722; CHECK-NEXT:  entry:723; CHECK-NEXT:    [[ADD_NUW:%.*]] = add nuw i32 [[ARG0]], [[ARG1]]724; CHECK-NEXT:    [[ADD_NSW:%.*]] = add nsw i32 [[ARG0]], [[ARG1]]725; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64726; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64727; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64728; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64729; CHECK-NEXT:    [[ADD_ZEXT:%.*]] = add i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]730; CHECK-NEXT:    [[ADD_SEXT:%.*]] = add i64 [[ARG0_SEXT]], [[ARG1_SEXT]]731; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW]])732; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NSW]])733; CHECK-NEXT:    call void @use.i64(i64 [[ADD_ZEXT]])734; CHECK-NEXT:    call void @use.i64(i64 [[ADD_SEXT]])735; CHECK-NEXT:    ret void736;737entry:738  %add.nuw = add nuw i32 %arg0, %arg1739  %add.nsw = add nsw i32 %arg0, %arg1740  %arg0.zext = zext i32 %arg0 to i64741  %arg1.zext = zext i32 %arg1 to i64742  %arg0.sext = sext i32 %arg0 to i64743  %arg1.sext = sext i32 %arg1 to i64744  %add.zext = add i64 %arg0.zext, %arg1.zext745  %add.sext = add i64 %arg0.sext, %arg1.sext746  call void @use.i32(i32 %add.nuw)747  call void @use.i32(i32 %add.nsw)748  call void @use.i64(i64 %add.zext)749  call void @use.i64(i64 %add.sext)750  ret void751}752 753; Both exist754define void @sub_zext_sub_sext__dominating_sub_nuw_sub_nsw(i32 %arg0, i32 %arg1) {755; CHECK-LABEL: define void @sub_zext_sub_sext__dominating_sub_nuw_sub_nsw756; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {757; CHECK-NEXT:  entry:758; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw i32 [[ARG0]], [[ARG1]]759; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG0]], [[ARG1]]760; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64761; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64762; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64763; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64764; CHECK-NEXT:    [[SUB_ZEXT:%.*]] = sub i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]765; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]766; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NUW]])767; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])768; CHECK-NEXT:    call void @use.i64(i64 [[SUB_ZEXT]])769; CHECK-NEXT:    call void @use.i64(i64 [[SUB_SEXT]])770; CHECK-NEXT:    ret void771;772entry:773  %sub.nuw = sub nuw i32 %arg0, %arg1774  %sub.nsw = sub nsw i32 %arg0, %arg1775  %arg0.zext = zext i32 %arg0 to i64776  %arg1.zext = zext i32 %arg1 to i64777  %arg0.sext = sext i32 %arg0 to i64778  %arg1.sext = sext i32 %arg1 to i64779  %sub.zext = sub i64 %arg0.zext, %arg1.zext780  %sub.sext = sub i64 %arg0.sext, %arg1.sext781  call void @use.i32(i32 %sub.nuw)782  call void @use.i32(i32 %sub.nsw)783  call void @use.i64(i64 %sub.zext)784  call void @use.i64(i64 %sub.sext)785  ret void786}787 788; Both exist with commuted operands from each other789define void @sub_zext_sub_sext__dominating_sub_nuw_sub_nsw_commuted(i32 %arg0, i32 %arg1) {790; CHECK-LABEL: define void @sub_zext_sub_sext__dominating_sub_nuw_sub_nsw_commuted791; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {792; CHECK-NEXT:  entry:793; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw i32 [[ARG0]], [[ARG1]]794; CHECK-NEXT:    [[SUB_NSW:%.*]] = sub nsw i32 [[ARG1]], [[ARG0]]795; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64796; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64797; CHECK-NEXT:    [[ARG0_SEXT:%.*]] = sext i32 [[ARG0]] to i64798; CHECK-NEXT:    [[ARG1_SEXT:%.*]] = sext i32 [[ARG1]] to i64799; CHECK-NEXT:    [[SUB_ZEXT:%.*]] = sub i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]800; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sub i64 [[ARG0_SEXT]], [[ARG1_SEXT]]801; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NUW]])802; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NSW]])803; CHECK-NEXT:    call void @use.i64(i64 [[SUB_ZEXT]])804; CHECK-NEXT:    call void @use.i64(i64 [[SUB_SEXT]])805; CHECK-NEXT:    ret void806;807entry:808  %sub.nuw = sub nuw i32 %arg0, %arg1809  %sub.nsw = sub nsw i32 %arg1, %arg0810  %arg0.zext = zext i32 %arg0 to i64811  %arg1.zext = zext i32 %arg1 to i64812  %arg0.sext = sext i32 %arg0 to i64813  %arg1.sext = sext i32 %arg1 to i64814  %sub.zext = sub i64 %arg0.zext, %arg1.zext815  %sub.sext = sub i64 %arg0.sext, %arg1.sext816  call void @use.i32(i32 %sub.nuw)817  call void @use.i32(i32 %sub.nsw)818  call void @use.i64(i64 %sub.zext)819  call void @use.i64(i64 %sub.sext)820  ret void821}822 823; --------------------------------------------------------------------824; zext x nuw+nsw825; --------------------------------------------------------------------826 827; Should fold out the add i64828define i64 @add_zext__dominating_add_nuw_nsw(i32 %arg0, i32 %arg1) {829; CHECK-LABEL: define i64 @add_zext__dominating_add_nuw_nsw830; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {831; CHECK-NEXT:  entry:832; CHECK-NEXT:    [[ADD_NUW_NSW:%.*]] = add nuw nsw i32 [[ARG0]], [[ARG1]]833; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64834; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64835; CHECK-NEXT:    [[ADD_ZEXT:%.*]] = add i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]836; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW_NSW]])837; CHECK-NEXT:    ret i64 [[ADD_ZEXT]]838;839entry:840  %add.nuw.nsw = add nuw nsw i32 %arg0, %arg1841  %arg0.zext = zext i32 %arg0 to i64842  %arg1.zext = zext i32 %arg1 to i64843  %add.zext = add i64 %arg0.zext, %arg1.zext844  call void @use.i32(i32 %add.nuw.nsw)845  ret i64 %add.zext846}847 848; Should fold out the add i64849define i64 @add_zext__dominating_add_nuw_nsw_commute(i32 %arg0, i32 %arg1) {850; CHECK-LABEL: define i64 @add_zext__dominating_add_nuw_nsw_commute851; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {852; CHECK-NEXT:  entry:853; CHECK-NEXT:    [[ADD_NUW_NSW:%.*]] = add nuw nsw i32 [[ARG0]], [[ARG1]]854; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64855; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64856; CHECK-NEXT:    [[ADD_ZEXT:%.*]] = add i64 [[ARG1_ZEXT]], [[ARG0_ZEXT]]857; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW_NSW]])858; CHECK-NEXT:    ret i64 [[ADD_ZEXT]]859;860entry:861  %add.nuw.nsw = add nuw nsw i32 %arg0, %arg1862  %arg0.zext = zext i32 %arg0 to i64863  %arg1.zext = zext i32 %arg1 to i64864  %add.zext = add i64 %arg1.zext, %arg0.zext865  call void @use.i32(i32 %add.nuw.nsw)866  ret i64 %add.zext867}868 869; Should fold out the sub i64870define i64 @sub_zext__dominating_sub_nuw_esw(i32 %arg0, i32 %arg1) {871; CHECK-LABEL: define i64 @sub_zext__dominating_sub_nuw_esw872; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {873; CHECK-NEXT:  entry:874; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw nsw i32 [[ARG0]], [[ARG1]]875; CHECK-NEXT:    [[ARG0_ZEXT:%.*]] = zext i32 [[ARG0]] to i64876; CHECK-NEXT:    [[ARG1_ZEXT:%.*]] = zext i32 [[ARG1]] to i64877; CHECK-NEXT:    [[SUB_ZEXT:%.*]] = sub i64 [[ARG0_ZEXT]], [[ARG1_ZEXT]]878; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NUW]])879; CHECK-NEXT:    ret i64 [[SUB_ZEXT]]880;881entry:882  %sub.nuw = sub nuw nsw i32 %arg0, %arg1883  %arg0.zext = zext i32 %arg0 to i64884  %arg1.zext = zext i32 %arg1 to i64885  %sub.zext = sub i64 %arg0.zext, %arg1.zext886  call void @use.i32(i32 %sub.nuw)887  ret i64 %sub.zext888}889 890; --------------------------------------------------------------------891; sext x nuw+nsw892; --------------------------------------------------------------------893 894; Should fold out the add i64895define i64 @add_sext__dominating_add_nuw_nsw(i32 %arg0, i32 %arg1) {896; CHECK-LABEL: define i64 @add_sext__dominating_add_nuw_nsw897; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {898; CHECK-NEXT:  entry:899; CHECK-NEXT:    [[ADD_NUW_NSW:%.*]] = add nuw nsw i32 [[ARG0]], [[ARG1]]900; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext i32 [[ADD_NUW_NSW]] to i64901; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW_NSW]])902; CHECK-NEXT:    ret i64 [[ADD_SEXT]]903;904entry:905  %add.nuw.nsw = add nuw nsw i32 %arg0, %arg1906  %arg0.sext = sext i32 %arg0 to i64907  %arg1.sext = sext i32 %arg1 to i64908  %add.sext = add i64 %arg0.sext, %arg1.sext909  call void @use.i32(i32 %add.nuw.nsw)910  ret i64 %add.sext911}912 913; Should fold out the add i64914define i64 @add_sext__dominating_add_nuw_nsw_commute(i32 %arg0, i32 %arg1) {915; CHECK-LABEL: define i64 @add_sext__dominating_add_nuw_nsw_commute916; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {917; CHECK-NEXT:  entry:918; CHECK-NEXT:    [[ADD_NUW_NSW:%.*]] = add nuw nsw i32 [[ARG0]], [[ARG1]]919; CHECK-NEXT:    [[ADD_SEXT:%.*]] = sext i32 [[ADD_NUW_NSW]] to i64920; CHECK-NEXT:    call void @use.i32(i32 [[ADD_NUW_NSW]])921; CHECK-NEXT:    ret i64 [[ADD_SEXT]]922;923entry:924  %add.nuw.nsw = add nuw nsw i32 %arg0, %arg1925  %arg0.sext = sext i32 %arg0 to i64926  %arg1.sext = sext i32 %arg1 to i64927  %add.sext = add i64 %arg1.sext, %arg0.sext928  call void @use.i32(i32 %add.nuw.nsw)929  ret i64 %add.sext930}931 932; Should fold out the sub i64933define i64 @sub_sext__dominating_sub_nuw_esw(i32 %arg0, i32 %arg1) {934; CHECK-LABEL: define i64 @sub_sext__dominating_sub_nuw_esw935; CHECK-SAME: (i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) #[[ATTR0]] {936; CHECK-NEXT:  entry:937; CHECK-NEXT:    [[SUB_NUW:%.*]] = sub nuw nsw i32 [[ARG0]], [[ARG1]]938; CHECK-NEXT:    [[SUB_SEXT:%.*]] = sext i32 [[SUB_NUW]] to i64939; CHECK-NEXT:    call void @use.i32(i32 [[SUB_NUW]])940; CHECK-NEXT:    ret i64 [[SUB_SEXT]]941;942entry:943  %sub.nuw = sub nuw nsw i32 %arg0, %arg1944  %arg0.sext = sext i32 %arg0 to i64945  %arg1.sext = sext i32 %arg1 to i64946  %sub.sext = sub i64 %arg0.sext, %arg1.sext947  call void @use.i32(i32 %sub.nuw)948  ret i64 %sub.sext949}950