1d4f4a1baSCraig Topper; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 24793c2c3SYingwei Zheng; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \ 3d4f4a1baSCraig Topper; RUN: | FileCheck %s -check-prefix=RV64I 4d4f4a1baSCraig Topper 5d4f4a1baSCraig Topper; Make sure we don't generate an addi in the loop in 6d4f4a1baSCraig Topper; addition to the addiw. Previously we type legalize the 7d4f4a1baSCraig Topper; setcc use using signext and the phi use using anyext. 8d4f4a1baSCraig Topper; We now detect when it would be beneficial to replace 9d4f4a1baSCraig Topper; anyext with signext. 10d4f4a1baSCraig Topper 11d4f4a1baSCraig Topperdefine void @quux(i32 signext %arg, i32 signext %arg1) nounwind { 12d4f4a1baSCraig Topper; RV64I-LABEL: quux: 13d4f4a1baSCraig Topper; RV64I: # %bb.0: # %bb 1403de1cb7SNikita Popov; RV64I-NEXT: beq a1, a0, .LBB0_4 15c4a60c9dSsgokhale; RV64I-NEXT: # %bb.1: # %bb2.preheader 16974e2e69SCraig Topper; RV64I-NEXT: addi sp, sp, -16 17974e2e69SCraig Topper; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 18974e2e69SCraig Topper; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 19974e2e69SCraig Topper; RV64I-NEXT: subw s0, a1, a0 20d4f4a1baSCraig Topper; RV64I-NEXT: .LBB0_2: # %bb2 21d4f4a1baSCraig Topper; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 22eabaee0cSFangrui Song; RV64I-NEXT: call hoge 23974e2e69SCraig Topper; RV64I-NEXT: addiw s0, s0, -1 24974e2e69SCraig Topper; RV64I-NEXT: bnez s0, .LBB0_2 25c4a60c9dSsgokhale; RV64I-NEXT: # %bb.3: 26974e2e69SCraig Topper; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 27974e2e69SCraig Topper; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 28974e2e69SCraig Topper; RV64I-NEXT: addi sp, sp, 16 29c4a60c9dSsgokhale; RV64I-NEXT: .LBB0_4: # %bb6 30d4f4a1baSCraig Topper; RV64I-NEXT: ret 31d4f4a1baSCraig Topperbb: 32d4f4a1baSCraig Topper %tmp = icmp eq i32 %arg, %arg1 33d4f4a1baSCraig Topper br i1 %tmp, label %bb6, label %bb2 34d4f4a1baSCraig Topper 35d4f4a1baSCraig Topperbb2: ; preds = %bb2, %bb 36d4f4a1baSCraig Topper %tmp3 = phi i32 [ %tmp4, %bb2 ], [ %arg, %bb ] 37d4f4a1baSCraig Topper tail call void @hoge() 38d4f4a1baSCraig Topper %tmp4 = add nsw i32 %tmp3, 1 39d4f4a1baSCraig Topper %tmp5 = icmp eq i32 %tmp4, %arg1 40d4f4a1baSCraig Topper br i1 %tmp5, label %bb6, label %bb2 41d4f4a1baSCraig Topper 42d4f4a1baSCraig Topperbb6: ; preds = %bb2, %bb 43d4f4a1baSCraig Topper ret void 44d4f4a1baSCraig Topper} 45d4f4a1baSCraig Topper 46d4f4a1baSCraig Topperdeclare void @hoge() 473b6dfa38SCraig Topper 483b6dfa38SCraig Topper; This ends up creating a shl with a i64 result type, but an i32 shift amount. 493b6dfa38SCraig Topper; Because custom type legalization for i32 is enabled, this resulted in 503b6dfa38SCraig Topper; LowerOperation being called for the amount. This was not expected and 513b6dfa38SCraig Topper; triggered an assert. 5239532ea0SCraig Topperdefine i32 @crash(i32 signext %x, i32 signext %y, i32 signext %z) { 533b6dfa38SCraig Topper; RV64I-LABEL: crash: 543b6dfa38SCraig Topper; RV64I: # %bb.0: 553b6dfa38SCraig Topper; RV64I-NEXT: seqz a3, a0 563b6dfa38SCraig Topper; RV64I-NEXT: addw a0, a1, a2 573b6dfa38SCraig Topper; RV64I-NEXT: slli a1, a3, 3 583b6dfa38SCraig Topper; RV64I-NEXT: .LBB1_1: # %bb 593b6dfa38SCraig Topper; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 603b6dfa38SCraig Topper; RV64I-NEXT: beq a0, a1, .LBB1_1 613b6dfa38SCraig Topper; RV64I-NEXT: # %bb.2: # %bar 623b6dfa38SCraig Topper; RV64I-NEXT: ret 633b6dfa38SCraig Topper br label %bb 643b6dfa38SCraig Topper 653b6dfa38SCraig Topperbb: 663b6dfa38SCraig Topper %a = icmp eq i32 %x, 0 673b6dfa38SCraig Topper %b = add i32 %y, %z 683b6dfa38SCraig Topper %c = select i1 %a, i32 8, i32 0 693b6dfa38SCraig Topper %d = icmp eq i32 %b, %c 703b6dfa38SCraig Topper br i1 %d, label %bb, label %bar 713b6dfa38SCraig Topper 723b6dfa38SCraig Topperbar: 733b6dfa38SCraig Topper ret i32 %b 743b6dfa38SCraig Topper} 75268371cfSCraig Topper 762ce25628SCraig Topper; We prefer to sign extend i32 constants for phis. The default behavior in 772ce25628SCraig Topper; SelectionDAGBuilder is zero extend. We have a target hook to override it. 782ce25628SCraig Topperdefine i64 @sext_phi_constants(i32 signext %c) { 792ce25628SCraig Topper; RV64I-LABEL: sext_phi_constants: 80268371cfSCraig Topper; RV64I: # %bb.0: 81*6657d4bdSPhilip Reames; RV64I-NEXT: beqz a0, .LBB2_2 82*6657d4bdSPhilip Reames; RV64I-NEXT: # %bb.1: 83*6657d4bdSPhilip Reames; RV64I-NEXT: li a0, -1 84*6657d4bdSPhilip Reames; RV64I-NEXT: j .LBB2_3 85*6657d4bdSPhilip Reames; RV64I-NEXT: .LBB2_2: # %iffalse 86*6657d4bdSPhilip Reames; RV64I-NEXT: li a0, -2 87*6657d4bdSPhilip Reames; RV64I-NEXT: .LBB2_3: # %merge 88*6657d4bdSPhilip Reames; RV64I-NEXT: slli a0, a0, 32 89a8c79121SCraig Topper; RV64I-NEXT: srli a0, a0, 32 90268371cfSCraig Topper; RV64I-NEXT: ret 91268371cfSCraig Topper %a = icmp ne i32 %c, 0 92268371cfSCraig Topper br i1 %a, label %iftrue, label %iffalse 93268371cfSCraig Topper 94268371cfSCraig Topperiftrue: 95268371cfSCraig Topper br label %merge 96268371cfSCraig Topper 97268371cfSCraig Topperiffalse: 98268371cfSCraig Topper br label %merge 99268371cfSCraig Topper 100268371cfSCraig Toppermerge: 101268371cfSCraig Topper %b = phi i32 [-1, %iftrue], [-2, %iffalse] 102268371cfSCraig Topper %d = zext i32 %b to i64 103268371cfSCraig Topper ret i64 %d 104268371cfSCraig Topper} 1054793c2c3SYingwei Zheng 1064793c2c3SYingwei Zheng; We prefer to sign extend i32 non-negative values. The default behavior in 1074793c2c3SYingwei Zheng; DAGCombiner is zero extend. We have a target hook to override it. 1084793c2c3SYingwei Zhengdefine signext i32 @square(i32 signext %num) { 1094793c2c3SYingwei Zheng; RV64I-LABEL: square: 1104793c2c3SYingwei Zheng; RV64I: # %bb.0: 1114793c2c3SYingwei Zheng; RV64I-NEXT: mulw a0, a0, a0 1124793c2c3SYingwei Zheng; RV64I-NEXT: ret 1134793c2c3SYingwei Zheng %mul = mul nsw i32 %num, %num 1144793c2c3SYingwei Zheng ret i32 %mul 1154793c2c3SYingwei Zheng} 116